diff --git a/.yamllint b/.yamllint new file mode 100644 index 0000000..811e0dd --- /dev/null +++ b/.yamllint @@ -0,0 +1,16 @@ +--- +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 + level: warning + indentation: + spaces: 2 + document-start: disable +... diff --git a/actions/python/code-quality/format/action.yaml b/actions/python/code-quality/format/action.yaml new file mode 100644 index 0000000..1fa3b6e --- /dev/null +++ b/actions/python/code-quality/format/action.yaml @@ -0,0 +1,137 @@ +--- +name: Format Code +description: Checks and ensures the code is formatted according to the defined + style guidelines. + +inputs: + os: + description: The operating system to use + default: ubuntu-latest + required: false + 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 + id: setup + continue-on-error: true + with: + os: ${{ inputs.os }} + python_version: ${{ inputs.python_version }} + poetry_install_options: ${{ inputs.poetry_install_options }} + poetry_export_options: ${{ inputs.poetry_export_options }} + + - name: Comment on PR + if: steps.setup.outcome == 'failure' + uses: elixir-cloud-aai/actions/github/comment@main + with: + ci_name: format + step_name: setup + commit_id: ${{ github.sha }} + issue_number: ${{ github.event.number }} + username: ${{ github.actor}} + message: | + **๐Ÿšจ CI Failure: Setup Step** + + Hi @${{ inputs.username }}, + + The **`format`** CI has encountered a failure during the + **`setup`** step. + + **Action Required:** + Please review your `pyproject.toml` file to ensure that the dependency groups, + especially the `code_quality` group, are correctly defined. + + **Environment Details:** +
+ Enviroment + - **Operating System:** ${{ inputs.os }} + - **Python Version:** ${{ inputs.python_version }} + - **Poetry Install Options:** `${{ inputs.poetry_install_options }}` + - **Poetry Export Options:** `${{ inputs.poetry_export_options }}` +
+ + If you need assistance, please refer to the [Poetry documentation](https://python-poetry.org/docs/), + or reach out to the maintainers. + + - name: Check code style + id: format + shell: bash + run: poetry run ruff format --check + + - name: Comment on PR + if: steps.format.outcome == 'failure' + uses: elixir-cloud-aai/actions/github/comment@main + with: + ci_name: format + step_name: format + commit_id: ${{ github.sha }} + continue-on-error: true + issue_number: ${{ github.event.number }} + username: ${{ github.actor}} + message: | + **๐Ÿ Linting Issues Detected: Ruff Analysis** + + Hi @${{ inputs.username }}, + + The **Ruff** linter has identified code style issues in the PR. + + --- + + ### **๐Ÿ“Œ Action Required** + + 1. **Run Ruff Locally:** + + Execute the following command to check and automatically fix + linting issues: + + ```bash + poetry run ruff format ${{ inputs.file_path }} + ``` + + --- + + ### **โ„น๏ธ Additional Information** + +
+ Using the Makefile Command + + For convenience, you can use the predefined Makefile command + to run Ruff: + + ```bash + make fl + ``` + + **Note:** + - Ensure you are in the root directory of your project before + running this command. + - The default Makefile from the Cookiecutter template includes + the `make fl` command. You can view all available Makefile commands + by running `make` without any arguments. + +
+ + --- + + ### **๐Ÿ”— Useful Resources** + + - [Ruff Documentation](https://docs.astral.sh/ruff/) +... diff --git a/actions/python/code-quality/lint/action.yaml b/actions/python/code-quality/lint/action.yaml new file mode 100644 index 0000000..0478e06 --- /dev/null +++ b/actions/python/code-quality/lint/action.yaml @@ -0,0 +1,132 @@ +--- +name: Lint Code +description: Lints the code to ensure code quality and adherence to standards. + +inputs: + os: + description: The operating system to use + default: ubuntu-latest + required: false + 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 + continue-on-error: true + with: + os: ${{ inputs.os }} + python_version: ${{ inputs.python_version }} + poetry_install_options: ${{ inputs.poetry_install_options }} + poetry_export_options: ${{ inputs.poetry_export_options }} + + - name: Comment on PR + if: steps.setup.outcome == 'failure' + uses: elixir-cloud-aai/actions/github/comment@main + with: + ci_name: lint + step_name: setup + commit_id: ${{ github.sha }} + issue_number: ${{ github.event.number }} + username: ${{ github.actor}} + message: | + **๐Ÿšจ CI Failure: Setup Step** + + Hi @${{ inputs.username }}, + + The **`lint`** CI has encountered a failure during the + **`setup`** step. + + **Action Required:** + Please review your `pyproject.toml` file to ensure that the dependency groups, + especially the `code_quality` group, are correctly defined. + + **Environment Details:** +
+ Enviroment + - **Operating System:** ${{ inputs.os }} + - **Python Version:** ${{ inputs.python_version }} + - **Poetry Install Options:** `${{ inputs.poetry_install_options }}` + - **Poetry Export Options:** `${{ inputs.poetry_export_options }}` +
+ + If you need assistance, please refer to the [Poetry documentation](https://python-poetry.org/docs/), + or reach out to the maintainers. + + - name: Check code quality + shell: bash + id: lint + run: poetry run ruff check . + + - name: Comment on PR + if: steps.lint.outcome == 'failure' + uses: elixir-cloud-aai/actions/github/comment@main + with: + ci_name: format + step_name: format + commit_id: ${{ github.sha }} + issue_number: ${{ github.event.number }} + username: ${{ github.actor}} + message: | + **๐Ÿ Linting Issues Detected: Ruff Analysis** + + Hi @${{ inputs.username }}, + + The **Ruff** linter has identified issues in your codebase. + + --- + + ### **๐Ÿ“Œ Action Required** + + 1. **Run Ruff Locally:** + + Execute the following command to check and automatically fix + linting issues: + + ```bash + poetry run ruff check --fix ${{ inputs.file_path }} + + --- + + ### **โ„น๏ธ Additional Information** + +
+ Using the Makefile Command + + For convenience, you can use the predefined Makefile command to run Ruff: + + ```bash + make fl + ``` + + **Note:** + - Ensure you are in the root directory of your project before running + this command. + - The default Makefile from the Cookiecutter template includes the + `make fl` command. You can view all available Makefile commands by + running `make` without any arguments. + +
+ + --- + + ### **๐Ÿ”— Useful Resources** + + - [Ruff Documentation](https://docs.astral.sh/ruff/) +... diff --git a/actions/python/code-quality/type-check/action.yaml b/actions/python/code-quality/type-check/action.yaml new file mode 100644 index 0000000..4f465ae --- /dev/null +++ b/actions/python/code-quality/type-check/action.yaml @@ -0,0 +1,225 @@ +--- +name: Type Check +description: Runs a type check on the codebase to ensure type safety and + correctness. + +inputs: + os: + description: The operating system to use + required: false + default: ubuntu-latest + 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 + id: setup + continue-on-error: true + with: + os: ${{ inputs.os }} + python_version: ${{ inputs.python_version }} + poetry_install_options: ${{ inputs.poetry_install_options }} + poetry_export_options: ${{ inputs.poetry_export_options }} + + - name: Comment on PR + if: steps.setup.outcome == 'failure' + uses: elixir-cloud-aai/actions/github/comment@main + with: + ci_name: type-check + step_name: setup + commit_id: ${{ github.sha }} + issue_number: ${{ github.event.number }} + username: ${{ github.actor}} + message: | + **๐Ÿšจ CI Failure: Setup Step** + + Hi @${{ inputs.username }}, + + The **`type check`** CI has encountered a failure during the + **`setup`** step. + + **Action Required:** + Please review your `pyproject.toml` file to ensure that the dependency groups, + especially the `types` group, are correctly defined. + + **Environment Details:** +
+ Enviroment + - **Operating System:** ${{ inputs.os }} + - **Python Version:** ${{ inputs.python_version }} + - **Poetry Install Options:** `${{ inputs.poetry_install_options }}` + - **Poetry Export Options:** `${{ inputs.poetry_export_options }}` +
+ + If you need assistance, please refer to the [Poetry documentation](https://python-poetry.org/docs/), + or reach out to the maintainers. + + - name: Check types + id: type-check + continue-on-error: true + shell: bash + run: poetry run mypy ${{ inputs.file_path }} + + - name: Comment on PR + if: steps.type-check.outcome == 'failure' + uses: elixir-cloud-aai/actions/github/comment@main + with: + ci_name: type-check + step_name: type-check + commit_id: ${{ github.sha }} + issue_number: ${{ github.event.number }} + username: ${{ github.actor}} + message: | + **โš ๏ธ Type Checking Failed: Mypy Analysis** + + Hi @${{ inputs.username }}, + + The **mypy** static type checker has identified type-related issues + in your codebase. + + --- + + ### **๐Ÿ“Œ Action Required** + + 1. **Run Mypy Locally:** + + Execute the following command to run **mypy** and view detailed + error reports: + + ```bash + poetry run mypy ${{ inputs.file_path }} + ``` + + 2. **Address Identified Issues:** + + - **Missing Stubs or Types:** Resolve any missing type annotations + or stubs as indicated by the error messages. + - **Type Inconsistencies:** Correct any type mismatches or + inconsistencies highlighted by **mypy**. + + --- + + ### **โ„น๏ธ Additional Information** + +
+ Handling Missing Stubs or Types + + If you encounter errors related to missing stubs or types, follow + these steps: + + 1. **Add Type Stubs:** + + Install type stubs for the affected packages using Poetry: + + ```bash + poetry add types- --group=types + ``` + + *Example:* + + ```bash + poetry add types-requests --group=types + ``` + + Alternatively, you can install stub packages if available: + + ```bash + poetry add -stub --group=types + ``` + + *Example:* + + ```bash + poetry add requests-stubs --group=types + ``` + + 2. **Manual Stub Creation:** + + If the package does not provide official stubs or if they are named + differently, you may need to create custom stubs or search for + third-party stubs. + + - **Search for Stubs:** Look for community-maintained stubs on + repositories like [Typeshed](https://github.com/python/typeshed) + or [Stub Packages](https://pypi.org/search/?q=stub). + + 3. **Update `pyproject.toml`:** + + Ensure your `pyproject.toml` includes the `types` group for + type stubs: + + ```toml + [tool.poetry.group.types.dependencies] + types- = "^" + ``` + + *Example:* + + ```toml + [tool.poetry.group.types.dependencies] + types-requests = "^2.25.11" + ``` + +
+ +
+ Ignoring Specific Errors + + If certain type errors are not relevant or are false positives, you + can configure **mypy** to ignore them. Add the module names under the + `[tool.mypy.overrides]` section in your `pyproject.toml`: + + ```toml + [[tool.mypy.overrides]] + ignore_missing_imports = true + module = [ + "connexion.*", + ] + ``` + + - **Granular Ignoring:** To avoid ignoring all errors, specify the + modules as granularly as possible. For instance, if you are using `x.y.z` + imports, add `x.y.z.*` instead of `x.*`. + + *Example:* + + ```toml + [[tool.mypy.overrides]] + ignore_missing_imports = true + module = [ + "connexion.api.*", + "connexion.server.*", + ] + ``` + +
+ + --- + + ### **๐Ÿ”— Useful Resources** + + - [Mypy Documentation](https://mypy.readthedocs.io/en/stable/) + - [Typeshed Repository](https://github.com/python/typeshed) + - [Best Practices for Type Checking](https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html) +... diff --git a/actions/python/code-test/integration-test/action.yaml b/actions/python/code-test/integration-test/action.yaml new file mode 100644 index 0000000..b8fda7f --- /dev/null +++ b/actions/python/code-test/integration-test/action.yaml @@ -0,0 +1,204 @@ +--- +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 + continue-on-error: true + id: setup + with: + os: ${{ inputs.os }} + python_version: ${{ inputs.python_version }} + poetry_install_options: ${{ inputs.poetry_install_options }} + poetry_export_options: ${{ inputs.poetry_export_options }} + + - name: Comment on PR + if: steps.setup.outcome == 'failure' + uses: elixir-cloud-aai/actions/github/comment@main + with: + ci_name: integration-test + step_name: setup + commit_id: ${{ github.sha }} + issue_number: ${{ github.event.number }} + username: ${{ github.actor}} + message: | + **๐Ÿšจ CI Failure: Setup Step** + + Hi @${{ inputs.username }}, + + The **`integration test`** CI has encountered a failure during the + **`setup`** step. + + **Action Required:** + Please review your `pyproject.toml` file to ensure that the dependency groups, + especially the `test` and `main` groups, are correctly defined. + + **Environment Details:** +
+ Enviroment + - **Operating System:** ${{ inputs.os }} + - **Python Version:** ${{ inputs.python_version }} + - **Poetry Install Options:** `${{ inputs.poetry_install_options }}` + - **Poetry Export Options:** `${{ inputs.poetry_export_options }}` +
+ + If you need assistance, please refer to the [Poetry documentation](https://python-poetry.org/docs/), + or reach out to the maintainers. + + - name: Run integration tests and generate coverage report + id: test + continue-on-error: true + shell: bash + run: | + poetry run pytest \ + --cov-report term \ + --cov-report xml:test_integration.xml \ + --cov=${{ inputs.file_path }} + + - name: Comment on PR + if: steps.upload.outcome == 'failure' + uses: elixir-cloud-aai/actions/github/comment@main + with: + ci_name: integration-test + step_name: test + commit_id: ${{ github.sha }} + issue_number: ${{ github.event.number }} + username: ${{ github.actor}} + message: | + **๐Ÿงช Unit Tests and Dependency Check Failed** + + Hi @${{ inputs.username }}, + + The **integration tests** in have encountered failures. + + --- + + ### **๐Ÿ“Œ Action Required** + + Please address the following to resolve the issues: + + 1. **Review integration Tests:** + + - **File Path:** `${{ inputs.file_path }}` + - Examine the failing integration tests to identify the root + cause of the failures. + + 2. **Check Dependencies:** + + - Open your `pyproject.toml` file. + - Ensure that all dependencies are correctly specified and + there are no version conflicts or missing packages. + + 3. **Run Tests Locally:** + + Execute the following command to run the unit tests and view + detailed error reports: + + ```bash + poetry run pytest --cov=${{ inputs.file_path }} + ``` + + --- + + ### **๐Ÿ”— Useful Resources** + + - [Pytest Documentation](https://docs.pytest.org/en/latest/) + - [Best Practices for Writing Tests](https://docs.pytest.org/en/latest/goodpractices.html) + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v4 + id: upload + with: + token: ${{ inputs.codecov_token }} + flags: test_integration + files: ./test_integration.xml + fail_ci_if_error: false + verbose: true + + - name: Comment on PR + if: ${{ inputs.codecov_token }} == null || ${{ inputs.codecov_token }} == '' + uses: elixir-cloud-aai/actions/github/comment@main + with: + ci_name: integration-test + step_name: upload + commit_id: ${{ github.sha }} + issue_number: ${{ github.event.number }} + username: ${{ github.actor}} + message: | + **๐Ÿšจ Codecov Token Missing** + + Hi @${{ inputs.username }}, + + The **Codecov** token is missing from your repository's secrets. As + a result, the coverage report was successfully generated but **was not + uploaded** to Codecov. + + --- + + ### **๐Ÿ“Œ Action Required** + + To ensure that coverage reports are uploaded correctly in future runs, + please follow these steps: + + 1. **Obtain the Codecov Token:** + + - If you do not have the Codecov token, you can retrieve it from + [Codecov account](https://codecov.io/). + - Navigate to repository settings within Codecov to find the token. + + 2. **Add the Token to GitHub Secrets:** + + - Go to your GitHub repository. + - Click on **Settings** > **Secrets and variables** > **Actions**. + - Click on **New repository secret**. + - Enter the following details: + - **Name:** `CODECOV_TOKEN` + - **Value:** *Your Codecov token* + - Click **Add secret** to save. + + 3. **Verify the Setup:** + + - After adding the secret, trigger the workflow again to ensure + that the coverage report is uploaded successfully. + - Check the GitHub Actions logs and Codecov dashboard for + confirmation. + + --- + + ### **๐Ÿ”— Useful Resources** + + - [Codecov Documentation](https://docs.codecov.io/docs) + - [GitHub Actions Secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets) + - [Managing Secrets in GitHub](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) +... diff --git a/actions/python/code-test/unit-test/action.yaml b/actions/python/code-test/unit-test/action.yaml new file mode 100644 index 0000000..d0f731a --- /dev/null +++ b/actions/python/code-test/unit-test/action.yaml @@ -0,0 +1,204 @@ +--- +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 + 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 + id: setup + 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: Comment on PR + if: steps.setup.outcome == 'failure' + uses: elixir-cloud-aai/actions/github/comment@main + with: + ci_name: unit-test + step_name: setup + commit_id: ${{ github.sha }} + issue_number: ${{ github.event.number }} + username: ${{ github.actor}} + message: | + **๐Ÿšจ CI Failure: Setup Step** + + Hi @${{ inputs.username }}, + + The **`unit test`** CI has encountered a failure during the + **`setup`** step. + + **Action Required:** + Please review your `pyproject.toml` file to ensure that the dependency groups, + especially the `test` and main groups, are correctly defined. + + **Environment Details:** +
+ Enviroment + - **Operating System:** ${{ inputs.os }} + - **Python Version:** ${{ inputs.python_version }} + - **Poetry Install Options:** `${{ inputs.poetry_install_options }}` + - **Poetry Export Options:** `${{ inputs.poetry_export_options }}` +
+ + If you need assistance, please refer to the [Poetry documentation](https://python-poetry.org/docs/), + or reach out to the maintainers. + + - name: Run unit tests and generate coverage report + id: unit-test + shell: bash + run: | + poetry run pytest \ + --cov-report term \ + --cov-report xml:test_unit.xml \ + --cov=${{ inputs.file_path }} + + - name: Comment on PR + if: steps.unit-test.outcome == 'failure' + uses: elixir-cloud-aai/actions/github/comment@main + with: + ci_name: unit-test + step_name: test + commit_id: ${{ github.sha }} + issue_number: ${{ github.event.number }} + username: ${{ github.actor}} + message: | + **๐Ÿงช Unit Tests and Dependency Check Failed** + + Hi @${{ inputs.username }}, + + The **unit tests** in your project have encountered failures, and + there might be issues with your dependencies as defined in + `pyproject.toml`. + + --- + + ### **๐Ÿ“Œ Action Required** + + Please address the following to resolve the issues: + + 1. **Review Unit Tests:** + + - **File Path:** `${{ inputs.file_path }}` + - Examine the failing unit tests to identify the root cause of + the failures. + + 2. **Check Dependencies:** + + - Open your `pyproject.toml` file. + - Ensure that all dependencies are correctly specified and + there are no version conflicts or missing packages. + + 3. **Run Unit Tests Locally:** + + Execute the following command to run the unit tests and view + detailed error reports: + + ```bash + poetry run pytest --cov=${{ inputs.file_path }} + ``` + + --- + + ### **๐Ÿ”— Useful Resources** + + - [Pytest Documentation](https://docs.pytest.org/en/latest/) + - [Best Practices for Writing Tests](https://docs.pytest.org/en/latest/goodpractices.html) + + - name: Upload coverage to Codecov + id: upload + uses: codecov/codecov-action@v4 + with: + token: ${{ inputs.codecov_token }} + flags: test_unit + files: ./test_unit.xml + fail_ci_if_error: false + verbose: true + + - name: Comment on PR + if: ${{ inputs.codecov_token == null || inputs.codecov_token == '' }} + uses: elixir-cloud-aai/actions/github/comment@main + with: + ci_name: unit-test + step_name: upload + commit_id: ${{ github.sha }} + issue_number: ${{ github.event.number }} + username: ${{ github.actor}} + message: | + **๐Ÿšจ Codecov Token Missing** + + Hi @${{ inputs.username }}, + + The **Codecov** token is missing from your repository's secrets. As + a result, the coverage report was successfully generated but **was not + uploaded** to Codecov. + + --- + + ### **๐Ÿ“Œ Action Required** + + To ensure that coverage reports are uploaded correctly in future runs, + please follow these steps: + + 1. **Obtain the Codecov Token:** + + - If you do not have the Codecov token, you can retrieve it from + [Codecov account](https://codecov.io/). + - Navigate to repository settings within Codecov to find the token. + + 2. **Add the Token to GitHub Secrets:** + + - Go to your GitHub repository. + - Click on **Settings** > **Secrets and variables** > **Actions**. + - Click on **New repository secret**. + - Enter the following details: + - **Name:** `CODECOV_TOKEN` + - **Value:** *Your Codecov token* + - Click **Add secret** to save. + + 3. **Verify the Setup:** + + - After adding the secret, trigger the workflow again to ensure + that the coverage report is uploaded successfully. + - Check the GitHub Actions logs and Codecov dashboard for + confirmation. + + --- + + ### **๐Ÿ”— Useful Resources** + + - [Codecov Documentation](https://docs.codecov.io/docs) + - [GitHub Actions Secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets) + - [Managing Secrets in GitHub](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) +... diff --git a/actions/python/comment/action.yaml b/actions/python/comment/action.yaml new file mode 100644 index 0000000..1e8be11 --- /dev/null +++ b/actions/python/comment/action.yaml @@ -0,0 +1,72 @@ +--- +name: Commenting bot to report CI failures +description: | + This action is used to comment on a pull request with the CI failure details. + It checks if the comment is already present and updates the comment with the + latest CI failure details. + +inputs: + ci_name: + description: The name of the CI + required: true + commit_id: + description: The commit id to use + required: true + error_after_comment: + description: Stop the workflow after commenting + required: false + default: "true" + issue_number: + description: The issue number to comment on + required: true + message: + description: The message to include in the comment + required: true + step_name: + description: The name of the step the failed in the + required: true + username: + description: The username to tag in the message + required: true + +runs: + using: composite + steps: + - name: Create the title of the comment + id: globals + shell: bash + run: | + echo "TITLE=Hey @$INPUT_USERNAME, \`$INPUT_CI_NAME\` CI failed at \`$INPUT_STEP_NAME\` step!" >> "${GITHUB_OUTPUT}" + env: + INPUT_USERNAME: ${{ inputs.username }} + INPUT_CI_NAME: ${{ inputs.ci_name }} + INPUT_STEP_NAME: ${{ inputs.step_name }} + + - name: Find if comment is already present + uses: peter-evans/find-comment@v3 + id: find-comment + with: + issue_number: ${{ inputs.issue_number }} + comment-author: github-actions[bot] + body-includes: ${{ steps.globals.outputs.TITLE }} + + - name: Create a new comment if there hasn't been one + if: steps.find-comment.outputs.comment-id == '' + id: fresh-comment + uses: peter-evans/create-or-update-comment@v4 + with: + issue_number: ${{ inputs.issue_number }} + body: | + ${{ steps.globals.outputs.TITLE }} + ${{ inputs.message }} + + - name: Fail or pass the workflow based on the input + shell: bash + run: | + if [[ "${{ inputs.error_after_comment }}" == "true" ]]; then + echo "Exiting the workflow as per the input" + exit 1 + else + echo "Continuing the workflow as per the input" + fi +... diff --git a/actions/python/docs/autogenerated-docs-check/action.yaml b/actions/python/docs/autogenerated-docs-check/action.yaml new file mode 100644 index 0000000..50dac72 --- /dev/null +++ b/actions/python/docs/autogenerated-docs-check/action.yaml @@ -0,0 +1,193 @@ +--- +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, default to the + package name from the pyproject.toml + required: false + 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: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up environment + id: setup + uses: elixir-cloud-aai/actions/python/setup/poetry@main + continue-on-error: true + with: + os: ${{ inputs.os }} + python-version: ${{ inputs.python_version }} + poetry-install-options: ${{ inputs.poetry_install_options }} + poetry-export-options: ${{ inputs.poetry_export_options }} + + - name: Comment on PR + if: steps.setup.outcome == 'failure' + uses: elixir-cloud-aai/actions/github/comment@main + with: + ci_name: docs + step_name: setup + commit_id: ${{ github.sha }} + issue_number: ${{ github.event.number }} + username: ${{ github.actor}} + message: | + **๐Ÿšจ CI Failure: Setup Step** + + Hi @${{ inputs.username }}, + + The **`docs check`** CI has encountered a failure during the + **`setup`** step. + + **Action Required:** + Please review your `pyproject.toml` file to ensure that the dependency groups, + especially the `docs`, `main` and `types` group, are correctly defined. + + **Environment Details:** +
+ Enviroment + - **Operating System:** ${{ inputs.os }} + - **Python Version:** ${{ inputs.python_version }} + - **Poetry Install Options:** `${{ inputs.poetry_install_options }}` + - **Poetry Export Options:** `${{ inputs.poetry_export_options }}` +
+ + If you need assistance, please refer to the [Poetry documentation](https://python-poetry.org/docs/), + or reach out to the maintainers. + + - name: Get the file_path if user doesn't provide it + id: get-file-path + shell: bash + run: | + if [[ -z "${{ inputs.file_path }}" ]]; then + file_path=$(poetry version | awk '{print $1}') + else + file_path="${{ inputs.file_path }}" + fi + echo "file_path=$file_path" >> $GITHUB_ENV + + # This should not be possible, but just in case + - name: Comment on PR + if: ${{ env.file_path }} == "" + uses: elixir-cloud-aai/actions/github/comment@main + with: + ci_name: docs + step_name: get-file-path + commit_id: ${{ github.sha }} + issue_number: ${{ github.event.number }} + username: ${{ github.actor}} + message: | + Couldn't retrieve project name from `pyproject.toml` and + `file_path`` is not provided for the workflow. + + - name: Generate API docs + shell: bash + run: | + poetry run sphinx-apidoc \ + -o /tmp/docs/source/pages \ + ${{ env.file_path }}/ + + - name: Compare current docs with latest docs + shell: bash + id: compare-docs + continue-on-error: true + run: | + shasum /tmp/docs/source/pages/* > /tmp/docs.sha + 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." + + - name: Comment on PR + if: steps.compare-docs.outcome == 'failure' + uses: elixir-cloud-aai/actions/github/comment@main + with: + ci_name: docs + step_name: compare-docs + commit_id: ${{ github.sha }} + issue_number: ${{ github.event.number }} + username: ${{ github.actor}} + message: | + **๐Ÿ”ง API Documentation Outdated** + + Hi @${{ inputs.username }}, + + The **API documentation** in the PR is outdated and needs to be + refreshed to reflect recent changes in the codebase. + + --- + + ### **๐Ÿ“Œ Action Required** + + Please update the API documentation by following these steps: + + 1. **Run Sphinx-Apidoc:** + + Execute the following command to regenerate the API documentation: + + ```bash + poetry run sphinx-apidoc ${{ env.file_path }} + ``` + + 2. **Verify Documentation:** + + After running the command, review the generated documentation to + ensure it accurately represents the current state of your codebase. + + --- + + ### **โ„น๏ธ Additional Information** + +
+ Using the Makefile Command + + For convenience, you can use the predefined Makefile command to + update the documentation: + + ```bash + make docs + ``` + + This command utilizes the `sphinx-apidoc` tool to regenerate the API + documentation based on your project's configuration. + + **Note:** The default Makefile from the Cookiecutter template + includes the `make docs` command. Ensure you are in the root + directory of your project before running this command. + +
+ + --- + + ### **๐Ÿ”— Useful Resources** + + - [Sphinx-Apidoc Documentation](https://www.sphinx-doc.org/en/master/man/sphinx-apidoc.html) +... diff --git a/actions/python/release/pypi/action.yaml b/actions/python/release/pypi/action.yaml new file mode 100644 index 0000000..617a874 --- /dev/null +++ b/actions/python/release/pypi/action.yaml @@ -0,0 +1,46 @@ +--- +name: Publish to PyPI +description: Publishes the Python package to PyPI when a release is made. + +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: "--only=main" + description: Additional options to pass to poetry install + required: false + poetry_export_options: + default: "--only=main" + description: Options to pass to poetry export for cache invalidation + required: false + pypi_token: + description: PYPI token for release the package + required: true + +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: Build package + shell: bash + run: poetry build + + - name: Publish package to PyPI + shell: bash + run: poetry publish -u __token__ -p ${{ inputs.pypi_token }} +... diff --git a/actions/python/setup/poetry/action.yaml b/actions/python/setup/poetry/action.yaml new file mode 100644 index 0000000..f9de61e --- /dev/null +++ b/actions/python/setup/poetry/action.yaml @@ -0,0 +1,151 @@ +--- +name: Setup Python and Poetry Action +description: Configure env, Python, Poetry, deps and cache management. + +inputs: + os: + default: ubuntu-latest + description: The operating system to use + python_version: + default: "3.12" + description: The version of Python to use + dependencies: + default: "" + description: > + A comma-separated list of dependencies to install via Poetry. + Example: "flask,black,flake8". If this option is provided, all other + Poetry options related to project dependencies will be ignored. + # Below are the options for installing and caching dependencies via poetry + poetry_version: + default: "1.8.4" + description: The version of Poetry to install + poetry_install_options: + default: "" + description: Additional options to pass to poetry install + poetry_export_options: + default: "" + description: > + Options to pass to poetry export for hash generation for cache + invalidation + +runs: + using: composite + steps: + - uses: "actions/setup-python@v5" + id: setup-python + with: + python-version: "${{ inputs.python_version }}" + + - name: Setup pipx environment Variables + id: pipx-env-setup + # pipx default home and bin dir are not writable by the cache action + # so override them here and add the bin dir to PATH for later steps. + # This also ensures the pipx cache only contains poetry + run: | + SEP="${{ !startsWith(runner.os, 'windows') && '/' || '\\' }}" + PIPX_CACHE="${{ github.workspace }}${SEP}pipx_cache" + echo "pipx-cache-path=${PIPX_CACHE}" >> $GITHUB_OUTPUT + echo "pipx-version=$(pipx --version)" >> $GITHUB_OUTPUT + echo "PIPX_HOME=${PIPX_CACHE}${SEP}home" >> $GITHUB_ENV + echo "PIPX_BIN_DIR=${PIPX_CACHE}${SEP}bin" >> $GITHUB_ENV + echo "PIPX_MAN_DIR=${PIPX_CACHE}${SEP}man" >> $GITHUB_ENV + echo "${PIPX_CACHE}${SEP}bin" >> $GITHUB_PATH + shell: bash + + - name: Pipx poetry cache, check if poetry is cached + id: pipx-poetry-cache + uses: actions/cache@v4 + with: + path: ${{ steps.pipx-env-setup.outputs.pipx-cache-path }} + key: > + ${{ runner.os }}- + py${{ inputs.python_version }}- + px${{ steps.pipx-env-setup.outputs.pipx-version }}- + pt${{ inputs.poetry_version }} + + - name: Install poetry, if poetry is not cached + if: ${{ steps.pipx-poetry-cache.outputs.cache-hit != 'true' }} + id: install-poetry + shell: bash + run: | + pipx install poetry \ + --python "${{ steps.setup-python.outputs.python-path }}" + pipx run poetry self add poetry-plugin-export@latest + + - name: Read poetry cache location + id: poetry-cache-location + shell: bash + run: | + echo "poetry-venv-location=$(poetry config virtualenvs.path)" \ + >> $GITHUB_OUTPUT + + # Generate DEP_HASH based on dependencies or poetry export options + - name: Generate DEP_HASH + run: | + if [ -n "${{ inputs.dependencies }}" ]; then + # Generate hash from dependencies list + echo "DEP_HASH=$( + echo '${{ inputs.dependencies }}' | + tr ',' '\n' | + sort | + sha256sum | + cut -d ' ' -f1 + )" >> $GITHUB_ENV + else + # Use poetry export options if provided + if [ -n "${{ inputs.poetry_export_options }}" ]; then + poetry export ${{ inputs.poetry_export_options }} \ + --format=requirements.txt \ + --output=requirements.txt + else + # Export all groups if no options provided + poetry export \ + --format=requirements.txt \ + --output=requirements.txt + fi + echo "DEP_HASH=$( + sha256sum requirements.txt | + cut -d ' ' -f 1 + )" >> $GITHUB_ENV + fi + shell: bash + + - name: Poetry dependency cache + uses: actions/cache@v4 + id: poetry-dep-cache + if: ${{ inputs.dependencies != '' }} + with: + path: ${{ steps.poetry-cache-location.outputs.poetry-venv-location }} + key: > + ${{ runner.os }}- + py${{ inputs.python_version }}- + hash${{ env.DEP_HASH }} + + - name: Install dependencies + if: ${{ inputs.dependencies != '' && steps.poetry-dep-cache.outputs.cache-hit != 'true' }} + shell: bash + run: | + # Initialize poetry if no pyproject.toml file is found + if [ ! -f pyproject.toml ]; then + poetry init --no-interaction + fi + # Install dependencies + poetry add $(echo ${{ inputs.dependencies }} | tr "," " ") --no-interaction + + - name: Poetry cache + id: poetry-cache + uses: actions/cache@v4 + if: ${{ inputs.dependencies == '' }} + with: + path: ${{ steps.poetry-cache-location.outputs.poetry-venv-location }} + key: > + ${{ runner.os }}- + py${{ inputs.python_version }}- + hash${{ env.DEP_HASH }}- + options${{ inputs.poetry_install_options }} + + - name: Poetry install + if: ${{ inputs.dependencies == '' && steps.poetry-cache.outputs.cache-hit != 'true' }} + shell: bash + run: poetry install ${{ inputs.poetry_install_options }} --no-interaction +... diff --git a/actions/python/vulnerability/code-vulnerability/action.yaml b/actions/python/vulnerability/code-vulnerability/action.yaml new file mode 100644 index 0000000..3a51655 --- /dev/null +++ b/actions/python/vulnerability/code-vulnerability/action.yaml @@ -0,0 +1,167 @@ +--- +name: Code Vulnerability Test +description: Set up environment, run code vulnerability checks, and report + findings. + +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: --only=vulnerability --no-root + description: Options for installing dependencies via poetry + required: false + poetry_export_options: + default: --only=vulnerability + description: Options for exporting dependencies for cache invalidation + required: false + config_path: + description: The path to the Bandit configuration file + default: pyproject.toml + required: false + file_path: + description: The path to the file or directory to check for vulnerabilities + required: true + +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 + id: setup + continue-on-error: false + with: + os: ${{ inputs.os }} + python_version: ${{ inputs.python_version }} + poetry_install_options: ${{ inputs.poetry_install_options }} + poetry_export_options: ${{ inputs.poetry_export_options }} + + - name: Comment on PR + if: steps.setup.outcome == 'failure' + uses: elixir-cloud-aai/actions/github/comment@main + with: + ci_name: bandit + step_name: setup + commit_id: ${{ github.sha }} + issue_number: ${{ github.event.number }} + username: ${{ github.actor}} + message: | + **๐Ÿšจ CI Failure: Setup Step** + + Hi @${{ inputs.username }}, + + The **`bandit`** CI has encountered a failure during the + **`setup`** step. + + **Action Required:** + Please review your `pyproject.toml` file to ensure that the dependency groups, + especially the `vulnerability` group, are correctly defined. + + **Environment Details:** +
+ Enviroment + - **Operating System:** ${{ inputs.os }} + - **Python Version:** ${{ inputs.python_version }} + - **Poetry Install Options:** `${{ inputs.poetry_install_options }}` + - **Poetry Export Options:** `${{ inputs.poetry_export_options }}` +
+ + If you need assistance, please refer to the [Poetry documentation](https://python-poetry.org/docs/), + or reach out to the maintainers. + + - name: Check code vulnerabilities with Bandit + id: check + continue-on-error: true + shell: bash + run: poetry run bandit \ + -c ${{ inputs.config_path }} \ + -r ${{ inputs.file_path }} + + - name: Comment on PR + if: steps.check.outcome == 'failure' + uses: elixir-cloud-aai/actions/github/comment@main + with: + ci_name: bandit + step_name: check + commit_id: ${{ github.sha }} + issue_number: ${{ github.event.number }} + username: ${{ github.actor}} + message: | + **๐Ÿ” Code Vulnerability Check Failed: Bandit Analysis** + + Hi @${{ inputs.username }}, + + The **`Bandit`** static analysis tool has identified potential + security vulnerabilities in your codebase during the **`bandit`** + analysis step. + + --- + + ### **๐Ÿ“Œ Action Required** + + Please review and address the identified vulnerabilities by following + these steps: + + 1. **Run Bandit Analysis:** + + Execute the following command to generate a detailed report of + the vulnerabilities: + + ```bash + poetry run bandit -c ${{ inputs.config_path }} -r ${{ inputs.file_path }} + ``` + + --- + + ### **๐Ÿ“Œ Ignoring False Positives** + + If you have verified that a reported vulnerability is a false + positive or is not applicable to your project, you can safely ignore + it by updating the `skips` list in your `pyproject.toml` file. + +
+ How to Ignore Specific Vulnerabilities + + Add the following configuration to your `pyproject.toml`: + + ```toml + [tool.bandit] + skips = [ + "B108" # Insecure usage of temp file/directory, false positive. + ] + ``` + + - **`"B108"`**: Replace with the specific vulnerability identifier + you wish to ignore. + - **`'Insecure usage of temp file/directory, false positive.'`**: + Provide a clear and concise reason for ignoring this vulnerability. + + **Example:** + + ```toml + [tool.bandit] + skips = [ + "B108" # Insecure usage of temp file/directory, false positive. + ] + ``` + + **Note:** Ensure that you have thoroughly reviewed the + vulnerabilities before choosing to ignore them to maintain the + security integrity of your project. + +
+ + --- + + ### **๐Ÿ”— Additional Resources** + + - [Bandit Documentation](https://bandit.readthedocs.io/en/latest/) +... diff --git a/actions/python/vulnerability/dependency-vulnerability/action.yaml b/actions/python/vulnerability/dependency-vulnerability/action.yaml new file mode 100644 index 0000000..f53d937 --- /dev/null +++ b/actions/python/vulnerability/dependency-vulnerability/action.yaml @@ -0,0 +1,138 @@ +--- +name: Dependency Vulnerability Test +description: Set up environment, run dependency vulnerability checks, and report findings. + +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: --only=vulnerability --no-root + description: Options for installing dependencies via poetry + required: false + poetry_export_options: + default: --only=vulnerability + description: Options for exporting dependencies for cache invalidation + required: false + +runs: + using: composite + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up environment + id: setup + continue-on-error: true + 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: Comment on PR + if: steps.setup.outcome == 'failure' + uses: elixir-cloud-aai/actions/github/comment@main + with: + ci_name: safety + step_name: setup + commit_id: ${{ github.sha }} + issue_number: ${{ github.event.number }} + username: ${{ github.actor}} + message: | + **๐Ÿšจ CI Failure: Setup Step** + + Hi @${{ inputs.username }}, + + The **`safety`** CI has encountered a failure during the + **`setup`** step. + + **Action Required:** + Please review your `pyproject.toml` file to ensure that the dependency groups, + especially the `vulnerability` group, are correctly defined. + + **Environment Details:** +
+ Enviroment + - **Operating System:** ${{ inputs.os }} + - **Python Version:** ${{ inputs.python_version }} + - **Poetry Install Options:** `${{ inputs.poetry_install_options }}` + - **Poetry Export Options:** `${{ inputs.poetry_export_options }}` +
+ + If you need assistance, please refer to the [Poetry documentation](https://python-poetry.org/docs/), + or reach out to the maintainers. + + - name: Check dependency vulnerabilities with Safety + shell: bash + id: check + continue-on-error: true + run: poetry run safety check --full-report + + - name: Comment on PR + if: steps.check.outcome == 'failure' + uses: elixir-cloud-aai/actions/github/comment@main + with: + ci_name: safety + step_name: check + commit_id: ${{ github.sha }} + issue_number: ${{ github.event.number }} + username: ${{ github.actor}} + message: | + **๐Ÿ” Code Vulnerability Check Failed** + + Hi @${{ inputs.username }}, + + The **`safety`** CLI has identified potential vulnerabilities in + dependencies. + + ### **Action Required:** + + Please review and address these vulnerabilities by executing the + following command: + + ```bash + poetry run safety check --full-report + ``` + + ### **๐Ÿ“Œ Ignoring False Positives** + + If you have verified that a reported vulnerability is a false + positive or is not applicable to your project, you can safely + ignore it by updating your `.safety-policy.yaml` file. + +
+ How to Ignore Specific Vulnerabilities + + Add the following configuration to `.safety-policy.yaml`: + + ```yaml + security: + ignore-vulnerabilities: + ERROR_CODE: + reason: 'REASON_FOR_IGNORING' + expires: 'YYYY-MM-DD' + ``` + + **Example:** + + ```yaml + security: + ignore-vulnerabilities: + CVE-2023-1234: + reason: 'False positive detected due to specific usage context.' + expires: '2024-12-31' + ``` + +
+ + ### **Additional Resources:** + + - [Safety CLI Documentation](https://pyup.io/safety/) +...