From a6e0aed7ae28f7aa14207e24bb7ebd807d7a764b Mon Sep 17 00:00:00 2001 From: Simon Kelly Date: Thu, 9 Jul 2026 14:31:27 +0200 Subject: [PATCH 1/2] Deprecate per-task actions Mirrors server-side deprecation (taskbadger/taskbadger#404). Emits a DeprecationWarning on the write paths; reads and the API are unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) --- taskbadger/cli/basics.py | 4 ++-- taskbadger/cli/wrapper.py | 2 +- taskbadger/sdk.py | 22 +++++++++++++++++++--- tests/test_sdk.py | 14 ++++++++++++++ 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/taskbadger/cli/basics.py b/taskbadger/cli/basics.py index d803cd8..db91eef 100644 --- a/taskbadger/cli/basics.py +++ b/taskbadger/cli/basics.py @@ -55,7 +55,7 @@ def create( "-a", metavar="", show_default=False, - help="Action definition e.g. 'success,error email to:me@email.com'", + help="[Deprecated] Action definition e.g. 'success,error email to:me@email.com'", ), status: StatusEnum = typer.Option(StatusEnum.PROCESSING, help="The initial status of the task."), value_max: int = typer.Option(100, help="The maximum value for the task."), @@ -118,7 +118,7 @@ def update( "-a", metavar="", show_default=False, - help="Action definition e.g. 'success,error email to:me@email.com'", + help="[Deprecated] Action definition e.g. 'success,error email to:me@email.com'", ), status: StatusEnum = typer.Option(StatusEnum.PROCESSING, help="The status of the task."), value: int = typer.Option(None, show_default=False, help="The current task value (progress)."), diff --git a/taskbadger/cli/wrapper.py b/taskbadger/cli/wrapper.py index 2a9cf16..ce4401f 100644 --- a/taskbadger/cli/wrapper.py +++ b/taskbadger/cli/wrapper.py @@ -17,7 +17,7 @@ def run( "-a", metavar="", show_default=False, - help="Action definition e.g. 'success,error email to:me@email.com'", + help="[Deprecated] Action definition e.g. 'success,error email to:me@email.com'", ), tag: list[str] = typer.Option( None, diff --git a/taskbadger/sdk.py b/taskbadger/sdk.py index d78b89b..9b71d94 100644 --- a/taskbadger/sdk.py +++ b/taskbadger/sdk.py @@ -163,7 +163,7 @@ def create_task( data: Custom task data. max_runtime: Maximum expected runtime (seconds). stale_timeout: Maximum allowed time between updates (seconds). - actions: Task actions. + actions: Task actions. **Deprecated:** use project-level actions instead. monitor_id: ID of the monitor to associate this task with. tags: Dictionary of namespace -> value tags. queue: Name of the queue the task is from. @@ -190,6 +190,7 @@ def create_task( data = data or {} task_dict["data"] = {**scope.context, **data} if actions: + _warn_actions_deprecated() task_dict["actions"] = [a.to_dict() for a in actions] if scope.tags or tags: tags = tags or {} @@ -234,7 +235,7 @@ def update_task( data: Custom task data. max_runtime: Maximum expected runtime (seconds). stale_timeout: Maximum allowed time between updates (seconds). - actions: Task actions. + actions: Task actions. **Deprecated:** use project-level actions instead. tags: Dictionary of namespace -> value tags. queue: Name of the queue the task is from. @@ -262,6 +263,7 @@ def update_task( queue=queue, ) if actions: + _warn_actions_deprecated() body.additional_properties = {"actions": [a.to_dict() for a in actions]} if tags: body.tags = PatchedTaskRequestTags.from_dict(tags) @@ -281,6 +283,16 @@ def list_tasks(page_size: int = None, cursor: str = None): return response.parsed +_ACTIONS_DEPRECATED_MESSAGE = ( + "Per-task actions are deprecated in favor of project-level actions and will be " + "removed in a future release. See https://docs.taskbadger.net/integrations/." +) + + +def _warn_actions_deprecated(): + warnings.warn(_ACTIONS_DEPRECATED_MESSAGE, DeprecationWarning, stacklevel=3) + + def _make_args(**kwargs): settings = Badger.current.settings ret_args = settings.as_kwargs() @@ -457,7 +469,11 @@ def update( self._task = task._task def add_actions(self, actions: list[Action]): - """Add actions to the task.""" + """Add actions to the task. + + **Deprecated:** per-task actions are deprecated in favor of project-level + actions and will be removed in a future release. + """ self.update(actions=actions) def tag(self, tags: dict[str, str]): diff --git a/tests/test_sdk.py b/tests/test_sdk.py index 343ade0..17878de 100644 --- a/tests/test_sdk.py +++ b/tests/test_sdk.py @@ -312,6 +312,20 @@ def test_add_actions(settings, patched_update): ) +def test_actions_deprecated(settings, patched_create, patched_update): + api_task = task_for_test() + patched_create.return_value = Response(HTTPStatus.OK, b"", {}, api_task) + patched_update.return_value = Response(HTTPStatus.OK, b"", {}, api_task) + + action = Action("success", integration=EmailIntegration(to="me@example.com")) + + with pytest.warns(DeprecationWarning, match="Per-task actions are deprecated"): + task = Task.create(name="task name", actions=[action]) + + with pytest.warns(DeprecationWarning, match="Per-task actions are deprecated"): + task.add_actions([action]) + + def test_action_validation(): WebhookIntegration(id="webhook:123") with pytest.raises(TaskbadgerException): From 9f523cbed70bc9677189402d694784eb8b9eb1c4 Mon Sep 17 00:00:00 2001 From: Simon Kelly Date: Thu, 9 Jul 2026 14:51:46 +0200 Subject: [PATCH 2/2] Update actions docs link Co-Authored-By: Claude Opus 4.8 (1M context) --- taskbadger/sdk.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/taskbadger/sdk.py b/taskbadger/sdk.py index 9b71d94..4d7fd85 100644 --- a/taskbadger/sdk.py +++ b/taskbadger/sdk.py @@ -285,7 +285,7 @@ def list_tasks(page_size: int = None, cursor: str = None): _ACTIONS_DEPRECATED_MESSAGE = ( "Per-task actions are deprecated in favor of project-level actions and will be " - "removed in a future release. See https://docs.taskbadger.net/integrations/." + "removed in a future release. See https://docs.taskbadger.net/actions/." )