Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .github/workflows/publish.yml
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I need some guidance for the publishing workflow. This is mostly copy-pasted from: https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/

Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: '3.9'
architecture: 'x64'
python-version: "3.x"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
pip install build twine

- name: Build source and binary distribution package
run: |
python setup.py sdist bdist_wheel
python -m build
env:
PACKAGE_VERSION: ${{ github.ref }}

Expand Down
13 changes: 3 additions & 10 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
django-version: '5.1'

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
Expand All @@ -34,23 +34,16 @@ jobs:
- name: Install dependencies and package
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -e ".[dev]"
pip install django~=${{ matrix.django-version }}.0

- name: Run lint and code review
run: |
pre-commit run --all-files
- name: Run tests with coverage
run: |
# prepare Django project: link all necessary data from the test project into the root directory
# Hint: Simply changing the directory does not work (leads to missing files in coverage report)
ln -s ./tests/core core
ln -s ./tests/testapp testapp
ln -s ./tests/manage.py manage.py
# run tests with coverage
coverage run \
--source='./django_future_tasks' \
manage.py test
pytest --cov=django_future_tasks tests
coverage xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ __pycache__
db.sqlite3
build/*
tests/static/*
.python-version
.coverage
uv.lock
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ repos:
- id: add-trailing-comma

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.9
rev: v0.12.8
hooks:
- id: ruff
- id: ruff-check
args: [ --fix ]
- id: ruff-format
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.3.2]

### Changed

- Migrate to `pytest`.
- Migrate to `pyproject.toml`.

## [1.3.1]

### Fixed

- Fix infinite loop in populate_periodic_future_tasks on IntegrityError

## [1.3.0]

### Added
Expand Down
54 changes: 54 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
[project]
name = "django-future-tasks"
description = "A library to create periodic, cron-like tasks or single tasks with a specified execution/start time and schedule it to run in the future."
readme = "README.md"
requires-python = ">=3.9"
license = {text = "MIT"}
authors = [
{name = "Armin Ster", email = "aster@anexia-it.com"},
]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Framework :: Django",
"Framework :: Django :: 4.2",
"Framework :: Django :: 5.0",
"Framework :: Django :: 5.1",
"Intended Audience :: Developers",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]
dynamic = ["version"]
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm not sure if this works in conjunction with the setup.py as-is.

dependencies = [
"croniter>=3.0.3,<3.1",
"django-cronfield>=0.2.0,<0.3",
]

[project.optional-dependencies]
dev = [
"django>=4.2,<5.2",
"pre-commit>=4.3,<4.4",
"pytest>=8.4,<8.5",
"pytest-cov>=7.0,<7.1",
"pytest-django>=4.11,<4.12",
"time-machine>=2.15.0,<2.17.0",
]

[project.urls]
Homepage = "https://github.com/anexia/django-future-tasks"
Documentation = "https://github.com/anexia/django-future-tasks/blob/main/README.md"
Repository = "https://github.com/anexia/django-future-tasks"
Issues = "https://github.com/anexia/django-future-tasks/issues"
Changelog = "https://github.com/anexia/django-future-tasks/blob/main/CHANGELOG.md"

[tool.pytest.ini_options]
DJANGO_SETTINGS_MODULE = "core.settings"

[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
Comment on lines +52 to +54
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The new build installs the django_future_tasks as editable package. Therefore, we can now run the tests inside the tests instead of the root folder, and we don't need any symlinks or python path customizations.

If one uses uv, the tests can be run via uv run --all-extras pytest tests which also sets up a venv, installls all necessary packages including the django_future_tasks as editable package and/or updates anything if necessary.

16 changes: 0 additions & 16 deletions requirements.txt

This file was deleted.

2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

setup(
name="django-future-tasks",
version=os.getenv("PACKAGE_VERSION", "1.3.0").replace("refs/tags/", ""),
version=os.getenv("PACKAGE_VERSION", "1.3.2").replace("refs/tags/", ""),
packages=find_packages(),
include_package_data=True,
install_requires=[
Expand Down
2 changes: 1 addition & 1 deletion tests/testapp/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ class TestappConfig(AppConfig):
name = "testapp"

# import signal handlers
import tests.testapp.handlers
import testapp.handlers
2 changes: 1 addition & 1 deletion tests/testapp/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from django.dispatch import receiver

from django_future_tasks.handlers import future_task_signal
from tests.core import settings
from core import settings


@receiver(future_task_signal, sender=intern(settings.FUTURE_TASK_TYPE_ONE))
Expand Down
24 changes: 12 additions & 12 deletions tests/testapp/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ def run(self):
class ProcessTasksCommandMixin:
@classmethod
def setUpClass(cls):
assert (
not hasattr(cls, "command_instance") or cls.command_instance is None
), "process_future_tasks has already been started"
assert not hasattr(cls, "command_instance") or cls.command_instance is None, (
"process_future_tasks has already been started"
)
print("Starting process_future_tasks...")

cls.command_instance = ProcessTasksCommand()
Expand All @@ -32,9 +32,9 @@ def setUpClass(cls):

@classmethod
def tearDownClass(cls):
assert (
cls.command_instance is not None
), "process_future_tasks has not been started and can therefore not be stopped"
assert cls.command_instance is not None, (
"process_future_tasks has not been started and can therefore not be stopped"
)
print("Stopping process_future_tasks...")

super().tearDownClass()
Expand All @@ -45,9 +45,9 @@ def tearDownClass(cls):
class PopulatePeriodicTaskCommandMixin:
@classmethod
def setUpClass(cls):
assert (
not hasattr(cls, "command_instance") or cls.command_instance is None
), "populate_periodic_future_tasks has already been started"
assert not hasattr(cls, "command_instance") or cls.command_instance is None, (
"populate_periodic_future_tasks has already been started"
)
print("Starting populate_periodic_future_tasks...")

cls.command_instance = PopulatePeriodicTasksCommand()
Expand All @@ -57,9 +57,9 @@ def setUpClass(cls):

@classmethod
def tearDownClass(cls):
assert (
cls.command_instance is not None
), "populate_periodic_future_tasks has not been started and can therefore not be stopped"
assert cls.command_instance is not None, (
"populate_periodic_future_tasks has not been started and can therefore not be stopped"
)
print("Stopping populate_periodic_future_tasks...")

super().tearDownClass()
Expand Down
4 changes: 2 additions & 2 deletions tests/testapp/tests/test_future_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
from django.utils import timezone

from django_future_tasks.models import FutureTask
from tests.core import settings
from tests.testapp.mixins import ProcessTasksCommandMixin
from core import settings
from testapp.mixins import ProcessTasksCommandMixin


class WaitForTaskStatusTimeout(Exception):
Expand Down
4 changes: 2 additions & 2 deletions tests/testapp/tests/test_periodic_future_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
from django.utils import timezone

from django_future_tasks.models import FutureTask, PeriodicFutureTask
from tests.core import settings
from tests.testapp.mixins import PopulatePeriodicTaskCommandMixin
from core import settings
from testapp.mixins import PopulatePeriodicTaskCommandMixin

SLEEP_TIME = 1.8

Expand Down