Skip to content

Commit

Permalink
Fix test matrix
Browse files Browse the repository at this point in the history
  • Loading branch information
AlvaroLQueiroz committed Apr 13, 2024
1 parent 30cf195 commit bb41d39
Show file tree
Hide file tree
Showing 20 changed files with 709 additions and 657 deletions.
105 changes: 105 additions & 0 deletions .github/workflows/ci.yml
@@ -0,0 +1,105 @@
# Based on
# https://pypi.org/project/tox-gh-actions/

---
name: Test the application.

on:
- push
- pull_request

jobs:
code-check:
name: Code checking
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install poetry
run: pipx install poetry
- name: Set python version for poetry
run: poetry env use python3.11
- name: Install dependencies
run: poetry install -E lint
- name: Run Isort
run: poetry run -v -- isort -c notifications/ sample_website/
- name: Run Black
run: poetry run -v -- black --check notifications/ sample_website/
- name: Run Pylint
run: poetry run -vvv -- pylint --rcfile=pyproject.toml --recursive=y -v notifications/ sample_website/
- name: Run Bandit
run: poetry run -v -- bandit -c pyproject.toml -r notifications/ sample_website/
- name: Run Mypy
run: poetry run -v -- mypy

test:
name: Testing
runs-on: ubuntu-latest
needs: code-check
strategy:
max-parallel: 4
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
django-version: ["3.2.0", "4.0.0", "4.1.0", "4.2.0"]
exclude:
- python-version: "3.11"
django-version: ["3.2", "4.0.0"]
- python-version: "3.12"
django-version: ["3.2", "4.0.0", "4.1.0"]

steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install poetry
run: pipx install poetry
- name: Set python version for poetry
run: poetry env use python${{ matrix.python-version }}
- name: Install Django
run: poetry add --lock django@~${{ matrix.django-version }}
- name: Install dependencies
run: poetry install -E test
- name: Run tests
run: poetry run -- pytest
env:
COVERAGE_FILE: ".coverage.${{ matrix.python-version }}.${{ matrix.django-version }}"
- name: Store coverage file
uses: actions/upload-artifact@v4
with:
name: coverage-${{ matrix.python-version }}-${{ matrix.django-version }}
path: .coverage.${{ matrix.python-version }}.${{ matrix.django-version }}


coverage:
name: Coverage
runs-on: ubuntu-latest
needs: test
permissions:
pull-requests: write
contents: write
steps:
- uses: actions/checkout@v4

- uses: actions/download-artifact@v4
id: download
with:
pattern: coverage-*
merge-multiple: true

- name: Coverage comment
id: coverage_comment
uses: py-cov-action/python-coverage-comment-action@v3
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MERGE_COVERAGE_FILES: true

- name: Store Pull Request comment to be posted
uses: actions/upload-artifact@v4
if: steps.coverage_comment.outputs.COMMENT_FILE_WRITTEN == 'true'
with:
name: python-coverage-comment-action
path: python-coverage-comment-action.txt
32 changes: 32 additions & 0 deletions .github/workflows/coverage.yml
@@ -0,0 +1,32 @@
name: Post coverage comment

on:
workflow_run:
workflows: ["CI"]
types:
- completed

jobs:
test:
name: Coverage
runs-on: ubuntu-latest
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
permissions:
# Gives the action the necessary permissions for publishing new
# comments in pull requests.
pull-requests: write
# Gives the action the necessary permissions for editing existing
# comments (to avoid publishing multiple comments in the same PR)
contents: write
# Gives the action the necessary permissions for looking up the
# workflow that launched this workflow, and download the related
# artifact that contains the comment to be published
actions: read
steps:
# DO NOT run actions/checkout here, for security reasons
# For details, refer to https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
- name: Post comment
uses: py-cov-action/python-coverage-comment-action@v3
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_PR_RUN_ID: ${{ github.event.workflow_run.id }}
87 changes: 0 additions & 87 deletions .github/workflows/test.yml

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -16,3 +16,4 @@ settings.json
.pytest_cache
.vscode
coverage.xml
TODO.md
8 changes: 6 additions & 2 deletions .pre-commit-config.yaml
Expand Up @@ -20,8 +20,7 @@ repos:
rev: v2.17.4
hooks:
- id: pylint
name: pylint
entry: poetry run pylint
entry: poetry run -- pylint
language: system
args: ["--rcfile=pyproject.toml"]

Expand All @@ -30,3 +29,8 @@ repos:
hooks:
- id: bandit
args: ["-c", "pyproject.toml"]

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.9.0
hooks:
- id: mypy
1 change: 1 addition & 0 deletions CHANGELOG.md
@@ -1,6 +1,7 @@
# Changelog

## 2.0.0
- Migrated to Github CI
- Added docker environment and migrated to Poetry and pyproject.toml
- Added verbose_name migration
- Migrated from `jsonfield` to Django `JSONField`
Expand Down
45 changes: 45 additions & 0 deletions CONTRIBUTING.md
@@ -0,0 +1,45 @@
# Creating the development environment

1. Install [Pyenv](https://github.com/pyenv/pyenv?tab=readme-ov-file#installation)
2. Install [PipX](https://github.com/pypa/pipx?tab=readme-ov-file#install-pipx)
3. Install [Poetry](https://python-poetry.org/docs/#installing-with-pipx) with **PipX**
4. install [Tox](https://tox.wiki/en/latest/installation.html#via-pipx) with **PipX**
5. Install necessary python versions

`pyenv install --skip-existing 3.8 3.9 3.10 3.11 3.12`

6. Set python versions as local

`pyenv local 3.12 3.11 3.10 3.9 3.8`

7. Ensure poetry config

`poetry config virtualenvs.create true`

`poetry config virtualenvs.prefer-active-python true`
8. Install the lib and dependencies with poetry

`poetry install --all-extras`

9. Initialize pre-commit

`poetry run pre-commit install`



# Running tests
To run the tests you can use any of the commands bellow:

1. `make tests` To run all tests over all environment combinations
2. `make test-latest` To run all tests over the latest enviroment possible

# Running code quality tools
To options to run the linters are:

1. `make isort`
2. `make black`
3. `make pylint`
4. `make bandit`
5. `make mypy`

To run all linters over all files: `make lint`
24 changes: 20 additions & 4 deletions Makefile
@@ -1,14 +1,18 @@
up:
docker-compose up --remove-orphans

tests:
poetry run python -m tox run-parallel
tox run-parallel -p auto

test-latest:
tox run -e py3.11-django42

server:
poetry run python manage.py runserver 0.0.0.0:8000

run: server

makemigrations:
migrations:
poetry run python manage.py makemigrations

migrate:
Expand All @@ -17,8 +21,20 @@ migrate:
shell:
poetry run python manage.py shell

isort:
poetry run pre-commit run --all-files isort

black:
poetry run pre-commit run --all-files black

pylint:
poetry run pylint --django-settings-module="notifications.settings" notifications/
poetry run pre-commit run --all-files pylint

bandit:
poetry run bandit -c pyproject.toml -r notifications/
poetry run pre-commit run --all-files bandit

mypy:
poetry run pre-commit run --all-files mypy

lint:
poetry run pre-commit run --all-files
2 changes: 1 addition & 1 deletion dockerfile
Expand Up @@ -20,4 +20,4 @@ RUN pyenv local system 3.8 3.9 3.10
RUN apt-get --purge autoremove -y gnupg; \
rm -rf /var/cache/apt/lists;

ENTRYPOINT poetry install && poetry run pre-commit install && /bin/bash
ENTRYPOINT poetry install && poetry run -- pre-commit install && /bin/bash
4 changes: 2 additions & 2 deletions notifications/admin.py
Expand Up @@ -28,9 +28,9 @@ def get_queryset(self, request: HttpRequest):
return qs.prefetch_related("actor")

@admin.action(description=gettext_lazy("Mark selected notifications as unread"))
def mark_unread(self, request: HttpRequest, queryset: NotificationQuerySet): # pylint: disable=unused-argument
def mark_unread(self, request: HttpRequest, queryset: NotificationQuerySet):
queryset.update(unread=True)

@admin.action(description=gettext_lazy("Mark selected notifications as read"))
def mark_read(self, request: HttpRequest, queryset: NotificationQuerySet): # pylint: disable=unused-argument
def mark_read(self, request: HttpRequest, queryset: NotificationQuerySet):
queryset.update(unread=False)
3 changes: 2 additions & 1 deletion notifications/models/base.py
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
import datetime
from typing import Union

from django.conf import settings
from django.contrib.contenttypes.fields import GenericForeignKey
Expand Down Expand Up @@ -130,7 +131,7 @@ def __str__(self):
return _("%(actor)s %(verb)s %(action_object)s %(timesince)s ago") % ctx
return _("%(actor)s %(verb)s %(timesince)s ago") % ctx

def timesince(self, now: None | datetime.datetime = None) -> str:
def timesince(self, now: Union[None, datetime.datetime] = None) -> str:
"""
Shortcut for the ``django.utils.timesince.timesince`` function of the
current timestamp.
Expand Down

0 comments on commit bb41d39

Please sign in to comment.