From fc8272f8f90fde7633a3970b99a94b7daffff8fe Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:54:45 -0300 Subject: [PATCH 01/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Add?= =?UTF-8?q?=20dotflow-cloud=20to=20cookiecutter=20cloud=20choices?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cookiecutter.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cookiecutter.json b/cookiecutter.json index db72c11..dd410d1 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -6,5 +6,5 @@ "execution_mode": ["sequential", "parallel", "background"], "retry": ["no", "yes"], "checkpoint": ["no", "yes"], - "cloud": ["none", "docker", "lambda", "lambda-scheduled", "lambda-s3-trigger", "lambda-sqs-trigger", "lambda-api-trigger", "ecs", "ecs-scheduled", "cloud-run", "cloud-run-scheduled", "kubernetes", "github-actions", "alibaba-fc", "alibaba-fc-scheduled"] + "cloud": ["none", "dotflow-cloud", "docker", "lambda", "lambda-scheduled", "lambda-s3-trigger", "lambda-sqs-trigger", "lambda-api-trigger", "ecs", "ecs-scheduled", "cloud-run", "cloud-run-scheduled", "kubernetes", "github-actions", "alibaba-fc", "alibaba-fc-scheduled"] } From 550f3a48fd2f5edae651ca0216b514e688873f43 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:54:48 -0300 Subject: [PATCH 02/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Expos?= =?UTF-8?q?e=20EXECUTION=5FMODE=20placeholder=20to=20cloud=20templates?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hooks/post_gen_project.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index 3920358..48dae38 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -11,6 +11,7 @@ CLOUD = "{{ cookiecutter.cloud }}" PROJECT_NAME = "{{ cookiecutter.project_name }}" MODULE_NAME = "{{ cookiecutter.module_name }}" +EXECUTION_MODE = "{{ cookiecutter.execution_mode }}" BOLD = "\033[1m" CYAN = "\033[36m" @@ -33,6 +34,7 @@ def ask_inputs() -> dict: "MODULE_NAME": MODULE_NAME, "STACK_NAME": sanitized_name, "K8S_NAME": sanitized_name, + "EXECUTION_MODE": EXECUTION_MODE, } if CLOUD in { From 8a252cfa2a3a56df3b7236664b0856fcce3d51fa Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:54:50 -0300 Subject: [PATCH 03/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Bump?= =?UTF-8?q?=20dotflow=20pin=20to=201.0.0.dev2=20and=20override=20scheduler?= =?UTF-8?q?=20for=20externally-scheduled=20clouds?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- {{cookiecutter.project_name}}/pyproject.toml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/{{cookiecutter.project_name}}/pyproject.toml b/{{cookiecutter.project_name}}/pyproject.toml index 8c61786..6608c98 100644 --- a/{{cookiecutter.project_name}}/pyproject.toml +++ b/{{cookiecutter.project_name}}/pyproject.toml @@ -1,15 +1,17 @@ +{%- set scheduled_clouds = ["dotflow-cloud", "lambda-scheduled", "ecs-scheduled", "cloud-run-scheduled", "alibaba-fc-scheduled", "github-actions"] -%} +{%- set scheduler = "none" if cookiecutter.cloud in scheduled_clouds else cookiecutter.scheduler -%} [project] name = "{{ cookiecutter.project_name }}" version = "0.1.0" description = "" requires-python = ">=3.9" dependencies = [ -{% if cookiecutter.storage == "s3" and cookiecutter.scheduler == "cron" %} "dotflow==0.15.0.dev7[aws,scheduler]", -{% elif cookiecutter.storage == "gcs" and cookiecutter.scheduler == "cron" %} "dotflow==0.15.0.dev7[gcp,scheduler]", -{% elif cookiecutter.storage == "s3" %} "dotflow==0.15.0.dev7[aws]", -{% elif cookiecutter.storage == "gcs" %} "dotflow==0.15.0.dev7[gcp]", -{% elif cookiecutter.scheduler == "cron" %} "dotflow==0.15.0.dev7[scheduler]", -{% else %} "dotflow==0.15.0.dev7", +{% if cookiecutter.storage == "s3" and scheduler == "cron" %} "dotflow==1.0.0.dev2[aws,scheduler]", +{% elif cookiecutter.storage == "gcs" and scheduler == "cron" %} "dotflow==1.0.0.dev2[gcp,scheduler]", +{% elif cookiecutter.storage == "s3" %} "dotflow==1.0.0.dev2[aws]", +{% elif cookiecutter.storage == "gcs" %} "dotflow==1.0.0.dev2[gcp]", +{% elif scheduler == "cron" %} "dotflow==1.0.0.dev2[scheduler]", +{% else %} "dotflow==1.0.0.dev2", {% endif %}] [project.optional-dependencies] From 0ff2583c6b30e56b90a045ad2041b05989c6cf29 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:54:51 -0300 Subject: [PATCH 04/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Conve?= =?UTF-8?q?rt=20workflow.py=20main()=20to=20factory=20with=20conditional?= =?UTF-8?q?=20internal=20start?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{{cookiecutter.module_name}}/workflow.py | 40 ++++++++----------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/{{cookiecutter.project_name}}/{{cookiecutter.module_name}}/workflow.py b/{{cookiecutter.project_name}}/{{cookiecutter.module_name}}/workflow.py index 85bf1d5..1a0eb26 100644 --- a/{{cookiecutter.project_name}}/{{cookiecutter.module_name}}/workflow.py +++ b/{{cookiecutter.project_name}}/{{cookiecutter.module_name}}/workflow.py @@ -1,3 +1,6 @@ +{%- set scheduled_clouds = ["dotflow-cloud", "lambda-scheduled", "ecs-scheduled", "cloud-run-scheduled", "alibaba-fc-scheduled", "github-actions"] -%} +{%- set scheduler = "none" if cookiecutter.cloud in scheduled_clouds else cookiecutter.scheduler -%} +{%- set needs_internal_start = cookiecutter.cloud in ["lambda", "lambda-scheduled", "lambda-s3-trigger", "lambda-sqs-trigger", "lambda-api-trigger", "alibaba-fc", "alibaba-fc-scheduled"] -%} {% if cookiecutter.checkpoint == "yes" -%} from uuid import uuid4 {% endif -%} @@ -9,25 +12,25 @@ {% elif cookiecutter.storage == "gcs" -%} from dotflow.providers import StorageGCS {% endif -%} -{% if cookiecutter.scheduler == "cron" -%} +{% if scheduler == "cron" -%} from dotflow.providers import SchedulerCron {% endif %} from {{ cookiecutter.module_name }}.actions import step_one, step_two -{% if cookiecutter.storage == "default" and cookiecutter.scheduler == "none" -%} +{% if cookiecutter.storage == "default" and scheduler == "none" -%} config = Config() -{% elif cookiecutter.storage == "default" and cookiecutter.scheduler == "cron" -%} +{% elif cookiecutter.storage == "default" and scheduler == "cron" -%} config = Config( scheduler=SchedulerCron(cron="*/5 * * * *"), ) -{% elif cookiecutter.storage == "file" and cookiecutter.scheduler == "none" -%} +{% elif cookiecutter.storage == "file" and scheduler == "none" -%} config = Config(storage=StorageFile()) -{% elif cookiecutter.storage == "file" and cookiecutter.scheduler == "cron" -%} +{% elif cookiecutter.storage == "file" and scheduler == "cron" -%} config = Config( storage=StorageFile(), scheduler=SchedulerCron(cron="*/5 * * * *"), ) -{% elif cookiecutter.storage == "s3" and cookiecutter.scheduler == "none" -%} +{% elif cookiecutter.storage == "s3" and scheduler == "none" -%} config = Config( storage=StorageS3( bucket="my-dotflow-bucket", @@ -35,7 +38,7 @@ region="us-east-1", ) ) -{% elif cookiecutter.storage == "s3" and cookiecutter.scheduler == "cron" -%} +{% elif cookiecutter.storage == "s3" and scheduler == "cron" -%} config = Config( storage=StorageS3( bucket="my-dotflow-bucket", @@ -44,7 +47,7 @@ ), scheduler=SchedulerCron(cron="*/5 * * * *"), ) -{% elif cookiecutter.storage == "gcs" and cookiecutter.scheduler == "none" -%} +{% elif cookiecutter.storage == "gcs" and scheduler == "none" -%} config = Config( storage=StorageGCS( bucket="my-dotflow-bucket", @@ -52,7 +55,7 @@ project="my-gcp-project", ) ) -{% elif cookiecutter.storage == "gcs" and cookiecutter.scheduler == "cron" -%} +{% elif cookiecutter.storage == "gcs" and scheduler == "cron" -%} config = Config( storage=StorageGCS( bucket="my-dotflow-bucket", @@ -63,7 +66,7 @@ ) {% endif %} -def main(): +def main() -> DotFlow: {%- if cookiecutter.checkpoint == "yes" %} workflow = DotFlow(config=config, workflow_id=uuid4()) {%- else %} @@ -72,22 +75,11 @@ def main(): workflow.task.add(step=step_one) workflow.task.add(step=step_two) - -{%- if cookiecutter.scheduler == "cron" and cookiecutter.checkpoint == "yes" %} - workflow.schedule(mode="{{ cookiecutter.execution_mode }}", resume=True) -{%- elif cookiecutter.scheduler == "cron" %} - workflow.schedule(mode="{{ cookiecutter.execution_mode }}") -{%- elif cookiecutter.checkpoint == "yes" %} +{% if needs_internal_start %} +{%- if cookiecutter.checkpoint == "yes" %} workflow.start(mode="{{ cookiecutter.execution_mode }}", resume=True) {%- else %} workflow.start(mode="{{ cookiecutter.execution_mode }}") {%- endif %} - - for task in workflow.result_task(): - print(f"Task {task.task_id}: {task.status}") - +{% endif %} return workflow - - -if __name__ == "__main__": - main() From 6a3b3c4ce61b83d0b53f48d1636f3761e18279f3 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:54:52 -0300 Subject: [PATCH 05/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Docum?= =?UTF-8?q?ent=20local=20run=20via=20dotflow=20start=20--workflow=20--mode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- {{cookiecutter.project_name}}/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_name}}/README.md b/{{cookiecutter.project_name}}/README.md index 1dd390e..f806c2a 100644 --- a/{{cookiecutter.project_name}}/README.md +++ b/{{cookiecutter.project_name}}/README.md @@ -16,7 +16,7 @@ A workflow built with [dotflow](https://github.com/dotflow-io/dotflow). ```bash pip install -e ".[dev]" -python -m {{ cookiecutter.module_name }}.workflow +dotflow start --workflow {{ cookiecutter.module_name }}.workflow:main --mode {{ cookiecutter.execution_mode }} ``` ## Running Tests From 35b60adc2a3b1e48f8769863d3e7f6c76453e4cd Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:02 -0300 Subject: [PATCH 06/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Switc?= =?UTF-8?q?h=20docker=20CMD=20to=20dotflow=20start=20--workflow=20with=20m?= =?UTF-8?q?ode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/docker/Dockerfile b/cloud/docker/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/docker/Dockerfile +++ b/cloud/docker/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] From 50a693ba77c028c056237c0e730a2736474665e9 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:02 -0300 Subject: [PATCH 07/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Switc?= =?UTF-8?q?h=20cloud-run=20CMD=20to=20dotflow=20start=20--workflow=20with?= =?UTF-8?q?=20mode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/cloud-run/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/cloud-run/Dockerfile b/cloud/cloud-run/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/cloud-run/Dockerfile +++ b/cloud/cloud-run/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] From 8afb7fba017f794a483e60529fb2d27aff558b3c Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:02 -0300 Subject: [PATCH 08/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Switc?= =?UTF-8?q?h=20cloud-run-scheduled=20CMD=20to=20dotflow=20start=20--workfl?= =?UTF-8?q?ow=20with=20mode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/cloud-run-scheduled/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/cloud-run-scheduled/Dockerfile b/cloud/cloud-run-scheduled/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/cloud-run-scheduled/Dockerfile +++ b/cloud/cloud-run-scheduled/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] From 921618740e486afcbe2bf0142b4164b83f07f519 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:02 -0300 Subject: [PATCH 09/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Switc?= =?UTF-8?q?h=20ecs=20CMD=20to=20dotflow=20start=20--workflow=20with=20mode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/ecs/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/ecs/Dockerfile b/cloud/ecs/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/ecs/Dockerfile +++ b/cloud/ecs/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] From c3c8269d561ac7008222b6a9f112ca5062eec10f Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:02 -0300 Subject: [PATCH 10/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Switc?= =?UTF-8?q?h=20ecs-scheduled=20CMD=20to=20dotflow=20start=20--workflow=20w?= =?UTF-8?q?ith=20mode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/ecs-scheduled/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/ecs-scheduled/Dockerfile b/cloud/ecs-scheduled/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/ecs-scheduled/Dockerfile +++ b/cloud/ecs-scheduled/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] From fdf68c977cf777f0dfdd48e6a5e686528f9f543c Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:02 -0300 Subject: [PATCH 11/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Switc?= =?UTF-8?q?h=20kubernetes=20CMD=20to=20dotflow=20start=20--workflow=20with?= =?UTF-8?q?=20mode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/kubernetes/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/kubernetes/Dockerfile b/cloud/kubernetes/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/kubernetes/Dockerfile +++ b/cloud/kubernetes/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] From 33b971ac09bdbb0e0e89b1581d4b0887032a5d57 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:02 -0300 Subject: [PATCH 12/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Switc?= =?UTF-8?q?h=20heroku=20CMD=20to=20dotflow=20start=20--workflow=20with=20m?= =?UTF-8?q?ode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/heroku/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/heroku/Dockerfile b/cloud/heroku/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/heroku/Dockerfile +++ b/cloud/heroku/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] From cf32d77e7e37937ac279e54c5b7fba112cfe8243 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:03 -0300 Subject: [PATCH 13/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Switc?= =?UTF-8?q?h=20fly-io=20CMD=20to=20dotflow=20start=20--workflow=20with=20m?= =?UTF-8?q?ode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/fly-io/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/fly-io/Dockerfile b/cloud/fly-io/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/fly-io/Dockerfile +++ b/cloud/fly-io/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] From 4e514c1c54d2d4cdb4a42e95655258ac5f346356 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:03 -0300 Subject: [PATCH 14/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Switc?= =?UTF-8?q?h=20railway=20CMD=20to=20dotflow=20start=20--workflow=20with=20?= =?UTF-8?q?mode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/railway/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/railway/Dockerfile b/cloud/railway/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/railway/Dockerfile +++ b/cloud/railway/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] From 633afe0f6b5ca76a435bff7624672e1c4fd1ae7c Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:03 -0300 Subject: [PATCH 15/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Switc?= =?UTF-8?q?h=20render=20CMD=20to=20dotflow=20start=20--workflow=20with=20m?= =?UTF-8?q?ode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/render/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/render/Dockerfile b/cloud/render/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/render/Dockerfile +++ b/cloud/render/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] From 5de92d177ef98363a94b9b47a5724f7bbec257a1 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:03 -0300 Subject: [PATCH 16/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Switc?= =?UTF-8?q?h=20digital-ocean=20CMD=20to=20dotflow=20start=20--workflow=20w?= =?UTF-8?q?ith=20mode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/digital-ocean/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/digital-ocean/Dockerfile b/cloud/digital-ocean/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/digital-ocean/Dockerfile +++ b/cloud/digital-ocean/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] From 1efab2dcd96b667aa81a2681202cd6f6816646b7 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:03 -0300 Subject: [PATCH 17/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Switc?= =?UTF-8?q?h=20azure-container=20CMD=20to=20dotflow=20start=20--workflow?= =?UTF-8?q?=20with=20mode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/azure-container/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/azure-container/Dockerfile b/cloud/azure-container/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/azure-container/Dockerfile +++ b/cloud/azure-container/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] From 63d59484f65c0518705f3a6e9a64d65efcbb00e0 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:08 -0300 Subject: [PATCH 18/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Use?= =?UTF-8?q?=20dotflow=20start=20--workflow=20in=20heroku=20Procfile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/heroku/Procfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/heroku/Procfile b/cloud/heroku/Procfile index 788b261..ec120a4 100644 --- a/cloud/heroku/Procfile +++ b/cloud/heroku/Procfile @@ -1 +1 @@ -worker: python -m {{MODULE_NAME}}.workflow +worker: dotflow start --workflow {{MODULE_NAME}}.workflow:main --mode {{EXECUTION_MODE}} From d6aef07ddb24caf35458c9d282a80798525afb2b Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:08 -0300 Subject: [PATCH 19/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Use?= =?UTF-8?q?=20dotflow=20start=20--workflow=20in=20heroku.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/heroku/heroku.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/cloud/heroku/heroku.yml b/cloud/heroku/heroku.yml index 9276305..1b34ba6 100644 --- a/cloud/heroku/heroku.yml +++ b/cloud/heroku/heroku.yml @@ -5,6 +5,9 @@ build: run: worker: command: - - python - - -m - - {{MODULE_NAME}}.workflow + - dotflow + - start + - --workflow + - {{MODULE_NAME}}.workflow:main + - --mode + - {{EXECUTION_MODE}} From 1a953e1b11ac9cd186ef7e8df48d34a16b31ec44 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:08 -0300 Subject: [PATCH 20/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Use?= =?UTF-8?q?=20dotflow=20start=20--workflow=20in=20fly.toml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/fly-io/fly.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/fly-io/fly.toml b/cloud/fly-io/fly.toml index 4f5d984..bac2764 100644 --- a/cloud/fly-io/fly.toml +++ b/cloud/fly-io/fly.toml @@ -5,7 +5,7 @@ primary_region = "iad" dockerfile = "Dockerfile" [processes] - worker = "python -m {{MODULE_NAME}}.workflow" + worker = "dotflow start --workflow {{MODULE_NAME}}.workflow:main --mode {{EXECUTION_MODE}}" [[vm]] cpu_kind = "shared" From 18e9d7b00629da742072160a7ead9fa5f2ee1e8a Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:08 -0300 Subject: [PATCH 21/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Use?= =?UTF-8?q?=20dotflow=20start=20--workflow=20in=20railway.json?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/railway/railway.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/railway/railway.json b/cloud/railway/railway.json index 8052ce1..c7c5153 100644 --- a/cloud/railway/railway.json +++ b/cloud/railway/railway.json @@ -5,7 +5,7 @@ "dockerfilePath": "Dockerfile" }, "deploy": { - "startCommand": "python -m {{MODULE_NAME}}.workflow", + "startCommand": "dotflow start --workflow {{MODULE_NAME}}.workflow:main --mode {{EXECUTION_MODE}}", "restartPolicyType": "ON_FAILURE", "restartPolicyMaxRetries": 3 } From 2fc1fe401addb412143445b6c5e02ba576182266 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:08 -0300 Subject: [PATCH 22/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Use?= =?UTF-8?q?=20dotflow=20start=20--workflow=20in=20github-actions=20workflo?= =?UTF-8?q?w?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/github-actions/.github/workflows/dotflow.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/github-actions/.github/workflows/dotflow.yml b/cloud/github-actions/.github/workflows/dotflow.yml index ce081f4..4efe244 100644 --- a/cloud/github-actions/.github/workflows/dotflow.yml +++ b/cloud/github-actions/.github/workflows/dotflow.yml @@ -17,4 +17,4 @@ jobs: - run: pip install -e . - - run: python -m {{MODULE_NAME}}.workflow + - run: dotflow start --workflow {{MODULE_NAME}}.workflow:main --mode {{EXECUTION_MODE}} From d13e58e5f85ba81058dec7285c2f61a1930a5656 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:33 -0300 Subject: [PATCH 23/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Simpl?= =?UTF-8?q?ify=20lambda=20handler=20to=20just=20call=20main()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/lambda/handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/lambda/handler.py b/cloud/lambda/handler.py index ddf4394..2b0d768 100644 --- a/cloud/lambda/handler.py +++ b/cloud/lambda/handler.py @@ -6,5 +6,5 @@ def handler(event, context): - result = main() + main() return {"statusCode": 200, "body": "workflow executed"} From 308ec79a67636d2d87887dd87ce0763110f60d8e Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:33 -0300 Subject: [PATCH 24/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Simpl?= =?UTF-8?q?ify=20lambda-scheduled=20handler=20to=20just=20call=20main()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/lambda-scheduled/handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/lambda-scheduled/handler.py b/cloud/lambda-scheduled/handler.py index 1234085..408f94a 100644 --- a/cloud/lambda-scheduled/handler.py +++ b/cloud/lambda-scheduled/handler.py @@ -7,5 +7,5 @@ def handler(event, context): """Invoked by EventBridge on a schedule.""" - result = main() + main() return {"statusCode": 200, "body": "workflow executed"} From d8d26dd657eb621d954bf9d37218479b783a16cd Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:33 -0300 Subject: [PATCH 25/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Simpl?= =?UTF-8?q?ify=20lambda-s3-trigger=20handler=20to=20just=20call=20main()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/lambda-s3-trigger/handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/lambda-s3-trigger/handler.py b/cloud/lambda-s3-trigger/handler.py index 7d09af8..8f22161 100644 --- a/cloud/lambda-s3-trigger/handler.py +++ b/cloud/lambda-s3-trigger/handler.py @@ -7,5 +7,5 @@ def handler(event, context): """Invoked by S3 file upload.""" - result = main() + main() return {"statusCode": 200, "body": "workflow executed"} From 012f4cabdb52ca4692790c9401d71eea857d6a8f Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:33 -0300 Subject: [PATCH 26/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Simpl?= =?UTF-8?q?ify=20lambda-sqs-trigger=20handler=20to=20just=20call=20main()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/lambda-sqs-trigger/handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/lambda-sqs-trigger/handler.py b/cloud/lambda-sqs-trigger/handler.py index 1c9f850..e41fd8b 100644 --- a/cloud/lambda-sqs-trigger/handler.py +++ b/cloud/lambda-sqs-trigger/handler.py @@ -12,5 +12,5 @@ def handler(event, context): body = json.loads(record.get("body", "{}")) print(f"Received message: {body}") - result = main() + main() return {"statusCode": 200, "body": "workflow executed"} From b66b879396a5000300d4581e67f207ff6da6403b Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:33 -0300 Subject: [PATCH 27/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Simpl?= =?UTF-8?q?ify=20lambda-api-trigger=20handler=20to=20just=20call=20main()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/lambda-api-trigger/handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/lambda-api-trigger/handler.py b/cloud/lambda-api-trigger/handler.py index e0db4a9..6e02fb4 100644 --- a/cloud/lambda-api-trigger/handler.py +++ b/cloud/lambda-api-trigger/handler.py @@ -11,5 +11,5 @@ def handler(event, context): body = json.loads(event.get("body") or "{}") print(f"Received payload: {body}") - result = main() + main() return {"statusCode": 200, "body": json.dumps({"status": "workflow executed"})} From f19d9d9e064f71cbd8b1f7780aa485f5af977c43 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:33 -0300 Subject: [PATCH 28/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Simpl?= =?UTF-8?q?ify=20alibaba-fc=20handler=20to=20just=20call=20main()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/alibaba-fc/handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/alibaba-fc/handler.py b/cloud/alibaba-fc/handler.py index ddf4394..2b0d768 100644 --- a/cloud/alibaba-fc/handler.py +++ b/cloud/alibaba-fc/handler.py @@ -6,5 +6,5 @@ def handler(event, context): - result = main() + main() return {"statusCode": 200, "body": "workflow executed"} From 85a662b258ee80cd935f187391ac8abf1943d28d Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:33 -0300 Subject: [PATCH 29/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Simpl?= =?UTF-8?q?ify=20alibaba-fc-scheduled=20handler=20to=20just=20call=20main(?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/alibaba-fc-scheduled/handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/alibaba-fc-scheduled/handler.py b/cloud/alibaba-fc-scheduled/handler.py index 40245d9..304da01 100644 --- a/cloud/alibaba-fc-scheduled/handler.py +++ b/cloud/alibaba-fc-scheduled/handler.py @@ -7,5 +7,5 @@ def handler(event, context): """Invoked by Timer Trigger on a schedule.""" - result = main() + main() return {"statusCode": 200, "body": "workflow executed"} From c04162d93844c76c3074a8d4f130e04e8975e3e1 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:37 -0300 Subject: [PATCH 30/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Add?= =?UTF-8?q?=20dotflow-cloud=20platform=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/dotflow-cloud/README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 cloud/dotflow-cloud/README.md diff --git a/cloud/dotflow-cloud/README.md b/cloud/dotflow-cloud/README.md new file mode 100644 index 0000000..f96b19b --- /dev/null +++ b/cloud/dotflow-cloud/README.md @@ -0,0 +1,28 @@ +# Dotflow Cloud + +Managed execution runtime for dotflow pipelines. Run your workflow on Dotflow Cloud without managing infrastructure. + +## Workflow entrypoint + +Your `workflow.py` must expose a `main()` factory that returns a `DotFlow` instance: + +```python +from dotflow import DotFlow + +def main() -> DotFlow: + workflow = DotFlow() + workflow.task.add(step=[...], initial_context=...) + return workflow +``` + +Dotflow Cloud runs it with the same contract used by: + +```bash +dotflow start --workflow .workflow:main +``` + +## Deploy + +```bash +dotflow deploy --platform dotflow-cloud --project +``` From 9debe429dec2edde6908298c54008db0bd188ddc Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:38 -0300 Subject: [PATCH 31/45] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20FEATURE-#22:=20Regis?= =?UTF-8?q?ter=20dotflow-cloud=20platform=20in=20cloud=20registry?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/registry.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cloud/registry.json b/cloud/registry.json index b9d051f..275150f 100644 --- a/cloud/registry.json +++ b/cloud/registry.json @@ -5,6 +5,11 @@ "description": "Dockerfile and docker-compose for local or any container runtime", "files": ["Dockerfile", "docker-compose.yml", "README.md"] }, + "dotflow-cloud": { + "name": "Dotflow Cloud", + "description": "Managed dotflow runtime with workflow factory entrypoint (dotflow start --workflow)", + "files": ["README.md"] + }, "lambda": { "name": "AWS Lambda", "description": "Dockerfile, handler.py, and SAM template for AWS Lambda", From 2170521043ef260cccbe6b972324e1d1187f9755 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:46 -0300 Subject: [PATCH 32/45] =?UTF-8?q?=F0=9F=93=98=20DOCS-#22:=20Update=20docke?= =?UTF-8?q?r=20README=20to=20reference=20new=20CMD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/docker/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/docker/README.md b/cloud/docker/README.md index 0de5d98..6ad61ff 100644 --- a/cloud/docker/README.md +++ b/cloud/docker/README.md @@ -15,5 +15,5 @@ docker compose up ## Important -- Do not rename the `workflow.py` module or the `main()` function — the `Dockerfile` CMD depends on it +- Do not rename `workflow.py` or the `main()` function — the `Dockerfile` runs `dotflow start --workflow .workflow:main` - The `docker-compose.yml` uses the `project_name` as container name From 8d09d7c73b6a714b6cdaec62854df632424f194c Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:46 -0300 Subject: [PATCH 33/45] =?UTF-8?q?=F0=9F=93=98=20DOCS-#22:=20Update=20cloud?= =?UTF-8?q?-run=20README=20to=20reference=20new=20CMD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/cloud-run/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/cloud-run/README.md b/cloud/cloud-run/README.md index d068b3e..296c73a 100644 --- a/cloud/cloud-run/README.md +++ b/cloud/cloud-run/README.md @@ -27,6 +27,6 @@ gcloud logging read "resource.type=cloud_run_revision AND resource.labels.servic ## Important -- Do not rename `workflow.py` or the `main()` function — the `Dockerfile` CMD depends on it +- Do not rename `workflow.py` or the `main()` function — the `Dockerfile` runs `dotflow start --workflow .workflow:main` - The `cloudbuild.yaml` references `gcp_project_id` and `gcp_region` — these must match your GCP project - Enable all required APIs before deploying From eaff7e4bb9278da2cb616988d9b5ca81f41d3a0b Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:46 -0300 Subject: [PATCH 34/45] =?UTF-8?q?=F0=9F=93=98=20DOCS-#22:=20Update=20cloud?= =?UTF-8?q?-run-scheduled=20README=20to=20reference=20new=20CMD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/cloud-run-scheduled/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/cloud-run-scheduled/README.md b/cloud/cloud-run-scheduled/README.md index 828c1ac..0621747 100644 --- a/cloud/cloud-run-scheduled/README.md +++ b/cloud/cloud-run-scheduled/README.md @@ -35,7 +35,7 @@ gcloud logging read "resource.type=cloud_run_revision AND resource.labels.servic ## Important -- Do not rename `workflow.py` or the `main()` function — the `Dockerfile` CMD depends on it +- Do not rename `workflow.py` or the `main()` function — the `Dockerfile` runs `dotflow start --workflow .workflow:main` - The `cloudbuild.yaml` references `gcp_project_id` and `gcp_region` — these must match your GCP project - Replace `` with the actual URL from the `gcloud run deploy` output - The scheduler uses OIDC authentication to invoke the Cloud Run service From b30369433795c615f4b3db4f4569920461f4332f Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:46 -0300 Subject: [PATCH 35/45] =?UTF-8?q?=F0=9F=93=98=20DOCS-#22:=20Update=20ecs?= =?UTF-8?q?=20README=20to=20reference=20new=20CMD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/ecs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/ecs/README.md b/cloud/ecs/README.md index e7f98d9..0d692c3 100644 --- a/cloud/ecs/README.md +++ b/cloud/ecs/README.md @@ -53,7 +53,7 @@ aws logs get-log-events --log-group-name /ecs/ \ ## Important -- Do not rename `workflow.py` or the `main()` function — the `Dockerfile` CMD depends on it +- Do not rename `workflow.py` or the `main()` function — the `Dockerfile` runs `dotflow start --workflow .workflow:main` - The `task-definition.json` references the ECR image URI, `executionRoleArn`, and CloudWatch log group — do not change these unless you also update the corresponding AWS resources - The `aws_account_id` and `aws_region` must match your actual AWS account and region - Create the CloudWatch log group before running the task, otherwise the container will fail to start From 3a026583c1048597455bf04b1b416162680aaab7 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:46 -0300 Subject: [PATCH 36/45] =?UTF-8?q?=F0=9F=93=98=20DOCS-#22:=20Update=20ecs-s?= =?UTF-8?q?cheduled=20README=20to=20reference=20new=20CMD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/ecs-scheduled/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/ecs-scheduled/README.md b/cloud/ecs-scheduled/README.md index 078d65c..7ba19ae 100644 --- a/cloud/ecs-scheduled/README.md +++ b/cloud/ecs-scheduled/README.md @@ -40,7 +40,7 @@ aws logs get-log-events --log-group-name /ecs/ \ ## Important -- Do not rename `workflow.py` or the `main()` function — the `Dockerfile` CMD depends on it +- Do not rename `workflow.py` or the `main()` function — the `Dockerfile` runs `dotflow start --workflow .workflow:main` - The schedule expression in `template.yaml` uses AWS EventBridge syntax - Edit `aws_account_id` and `aws_region` in `template.yaml` before deploying - The ECS task runs on Fargate and stops after the workflow completes From e57f5da078e517c5327536d1a80987a3f28a3fc5 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:46 -0300 Subject: [PATCH 37/45] =?UTF-8?q?=F0=9F=93=98=20DOCS-#22:=20Update=20kuber?= =?UTF-8?q?netes=20README=20to=20reference=20new=20CMD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/kubernetes/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/kubernetes/README.md b/cloud/kubernetes/README.md index 4262de6..a442fee 100644 --- a/cloud/kubernetes/README.md +++ b/cloud/kubernetes/README.md @@ -43,6 +43,6 @@ kubectl apply -f service.yaml ## Important -- Do not rename `workflow.py` or the `main()` function — the `Dockerfile` CMD depends on it +- Do not rename `workflow.py` or the `main()` function — the `Dockerfile` runs `dotflow start --workflow .workflow:main` - The `deployment.yaml` uses `imagePullPolicy: Never` by default — this only works with locally built images (minikube). For production, change to `Always` and use a container registry - Project names with `_` are automatically converted to `-` in Kubernetes resource names (RFC 1123 compliance) From 438ec7f52b06a48e8aaa6f33a788b8f6bd870d49 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:46 -0300 Subject: [PATCH 38/45] =?UTF-8?q?=F0=9F=93=98=20DOCS-#22:=20Update=20lambd?= =?UTF-8?q?a=20README=20for=20main-internal=20start=20contract?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/lambda/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/lambda/README.md b/cloud/lambda/README.md index 6b9b211..e69dc76 100644 --- a/cloud/lambda/README.md +++ b/cloud/lambda/README.md @@ -35,6 +35,6 @@ sam logs --stack-name --tail ## Important - Do not rename `handler.py` or the `handler()` function — the `Dockerfile` CMD is `handler.handler` -- Do not rename `workflow.py` or the `main()` function — `handler.py` imports it +- Do not rename `workflow.py` or the `main()` function — `handler.py` calls `main()` which starts the workflow internally - The `samconfig.toml` has the stack name, region, and ECR repository pre-configured from cookiecutter - To change the schedule or add triggers, edit `template.yaml` (see `lambda-scheduled` template) From 9408c612646c29c48d830559c29592afc02becec Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:46 -0300 Subject: [PATCH 39/45] =?UTF-8?q?=F0=9F=93=98=20DOCS-#22:=20Update=20lambd?= =?UTF-8?q?a-scheduled=20README=20for=20main-internal=20start=20contract?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/lambda-scheduled/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/lambda-scheduled/README.md b/cloud/lambda-scheduled/README.md index c1f908b..8d43ade 100644 --- a/cloud/lambda-scheduled/README.md +++ b/cloud/lambda-scheduled/README.md @@ -35,6 +35,6 @@ sam logs --stack-name --tail ## Important - Do not rename `handler.py` or the `handler()` function — the `Dockerfile` CMD is `handler.handler` -- Do not rename `workflow.py` or the `main()` function — `handler.py` imports it +- Do not rename `workflow.py` or the `main()` function — `handler.py` calls `main()` which starts the workflow internally - The schedule expression in `template.yaml` uses AWS EventBridge syntax (e.g. `rate(6 hours)`, `cron(0 12 * * ? *)`) - The `samconfig.toml` has stack name, region, and ECR repository pre-configured From 412b02bdc3dd58d0fbd9004844786af500b829f7 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:47 -0300 Subject: [PATCH 40/45] =?UTF-8?q?=F0=9F=93=98=20DOCS-#22:=20Update=20lambd?= =?UTF-8?q?a-s3-trigger=20README=20for=20main-internal=20start=20contract?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/lambda-s3-trigger/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/lambda-s3-trigger/README.md b/cloud/lambda-s3-trigger/README.md index 391259c..2a5d196 100644 --- a/cloud/lambda-s3-trigger/README.md +++ b/cloud/lambda-s3-trigger/README.md @@ -41,6 +41,6 @@ sam logs --stack-name --tail ## Important - Do not rename `handler.py` or the `handler()` function — the `Dockerfile` CMD is `handler.handler` -- Do not rename `workflow.py` or the `main()` function — `handler.py` imports it +- Do not rename `workflow.py` or the `main()` function — `handler.py` calls `main()` which starts the workflow internally - Edit the S3 bucket name and prefix in `template.yaml` before deploying - The `samconfig.toml` has stack name, region, and ECR repository pre-configured From 66f819426936c901723ec47d5452d5998bf7364f Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:47 -0300 Subject: [PATCH 41/45] =?UTF-8?q?=F0=9F=93=98=20DOCS-#22:=20Update=20lambd?= =?UTF-8?q?a-sqs-trigger=20README=20for=20main-internal=20start=20contract?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/lambda-sqs-trigger/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/lambda-sqs-trigger/README.md b/cloud/lambda-sqs-trigger/README.md index 1306e70..e2fcf5f 100644 --- a/cloud/lambda-sqs-trigger/README.md +++ b/cloud/lambda-sqs-trigger/README.md @@ -41,6 +41,6 @@ sam logs --stack-name --tail ## Important - Do not rename `handler.py` or the `handler()` function — the `Dockerfile` CMD is `handler.handler` -- Do not rename `workflow.py` or the `main()` function — `handler.py` imports it +- Do not rename `workflow.py` or the `main()` function — `handler.py` calls `main()` which starts the workflow internally - The SQS queue is created by the SAM template — check `template.yaml` for queue configuration - The `samconfig.toml` has stack name, region, and ECR repository pre-configured From 2e034b63b648e4c09da51746e6243c78666fac3d Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:47 -0300 Subject: [PATCH 42/45] =?UTF-8?q?=F0=9F=93=98=20DOCS-#22:=20Update=20lambd?= =?UTF-8?q?a-api-trigger=20README=20for=20main-internal=20start=20contract?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/lambda-api-trigger/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/lambda-api-trigger/README.md b/cloud/lambda-api-trigger/README.md index 26cf7ce..9c15e00 100644 --- a/cloud/lambda-api-trigger/README.md +++ b/cloud/lambda-api-trigger/README.md @@ -45,6 +45,6 @@ sam logs --stack-name --tail ## Important - Do not rename `handler.py` or the `handler()` function — the `Dockerfile` CMD is `handler.handler` -- Do not rename `workflow.py` or the `main()` function — `handler.py` imports it +- Do not rename `workflow.py` or the `main()` function — `handler.py` calls `main()` which starts the workflow internally - The API Gateway URL is shown in the CloudFormation outputs after deploy - The `samconfig.toml` has stack name, region, and ECR repository pre-configured From f8ddc4fb66afdfb68e984ff0301291f54d46d871 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:47 -0300 Subject: [PATCH 43/45] =?UTF-8?q?=F0=9F=93=98=20DOCS-#22:=20Update=20aliba?= =?UTF-8?q?ba-fc=20README=20for=20main-internal=20start=20contract?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/alibaba-fc/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/alibaba-fc/README.md b/cloud/alibaba-fc/README.md index 7f7ad12..21baf61 100644 --- a/cloud/alibaba-fc/README.md +++ b/cloud/alibaba-fc/README.md @@ -45,6 +45,6 @@ s logs --tail ## Important - Do not rename `handler.py` or the `handler()` function — `s.yaml` references `handler.handler` -- Do not rename `workflow.py` or the `main()` function — `handler.py` imports it +- Do not rename `workflow.py` or the `main()` function — `handler.py` calls `main()` which starts the workflow internally - The `s.yaml` has the function name, region, and container image pre-configured from cookiecutter - To add triggers (HTTP, timer, OSS, etc.), edit the `triggers` section in `s.yaml` From 27e4efddab78251ba6f8f56c3d127a30d7453bf3 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 18:55:47 -0300 Subject: [PATCH 44/45] =?UTF-8?q?=F0=9F=93=98=20DOCS-#22:=20Update=20aliba?= =?UTF-8?q?ba-fc-scheduled=20README=20for=20main-internal=20start=20contra?= =?UTF-8?q?ct?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud/alibaba-fc-scheduled/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/alibaba-fc-scheduled/README.md b/cloud/alibaba-fc-scheduled/README.md index f0f6a04..5bb0a44 100644 --- a/cloud/alibaba-fc-scheduled/README.md +++ b/cloud/alibaba-fc-scheduled/README.md @@ -56,7 +56,7 @@ The timer trigger uses **cron expressions** (China Standard Time — UTC+8): ## Important - Do not rename `handler.py` or the `handler()` function — `s.yaml` references `handler.handler` -- Do not rename `workflow.py` or the `main()` function — `handler.py` imports it +- Do not rename `workflow.py` or the `main()` function — `handler.py` calls `main()` which starts the workflow internally - The `s.yaml` has the function name, region, container image, and schedule pre-configured from cookiecutter - Timer triggers use China Standard Time (CST/UTC+8) by default - To change the schedule after deploy, edit `cronExpression` in `s.yaml` and run `s deploy` again From 35ab9bcebc3414ab428b3a4dccfab96b9c1f8047 Mon Sep 17 00:00:00 2001 From: Fernando Celmer Date: Tue, 14 Apr 2026 19:16:57 -0300 Subject: [PATCH 45/45] =?UTF-8?q?=F0=9F=93=A6=20PyPI:=20Update=20dotflow?= =?UTF-8?q?=20to=201.0.0.dev3=20in=20cookiecutter=20template?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- {{cookiecutter.project_name}}/pyproject.toml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/{{cookiecutter.project_name}}/pyproject.toml b/{{cookiecutter.project_name}}/pyproject.toml index 6608c98..a5e3255 100644 --- a/{{cookiecutter.project_name}}/pyproject.toml +++ b/{{cookiecutter.project_name}}/pyproject.toml @@ -6,12 +6,12 @@ version = "0.1.0" description = "" requires-python = ">=3.9" dependencies = [ -{% if cookiecutter.storage == "s3" and scheduler == "cron" %} "dotflow==1.0.0.dev2[aws,scheduler]", -{% elif cookiecutter.storage == "gcs" and scheduler == "cron" %} "dotflow==1.0.0.dev2[gcp,scheduler]", -{% elif cookiecutter.storage == "s3" %} "dotflow==1.0.0.dev2[aws]", -{% elif cookiecutter.storage == "gcs" %} "dotflow==1.0.0.dev2[gcp]", -{% elif scheduler == "cron" %} "dotflow==1.0.0.dev2[scheduler]", -{% else %} "dotflow==1.0.0.dev2", +{% if cookiecutter.storage == "s3" and scheduler == "cron" %} "dotflow==1.0.0.dev3[aws,scheduler]", +{% elif cookiecutter.storage == "gcs" and scheduler == "cron" %} "dotflow==1.0.0.dev3[gcp,scheduler]", +{% elif cookiecutter.storage == "s3" %} "dotflow==1.0.0.dev3[aws]", +{% elif cookiecutter.storage == "gcs" %} "dotflow==1.0.0.dev3[gcp]", +{% elif scheduler == "cron" %} "dotflow==1.0.0.dev3[scheduler]", +{% else %} "dotflow==1.0.0.dev3", {% endif %}] [project.optional-dependencies]