From 60ad36f839dee72c761e5ad299978a713da3e88e Mon Sep 17 00:00:00 2001 From: Jonathan Dobson Date: Wed, 6 Aug 2025 15:49:44 -0400 Subject: [PATCH] Jon/sky 5803 create workflow scripts table (#3120) --- ...2fe3e908a028_add_workflow_scripts_table.py | 56 +++++++++++++++++++ skyvern/forge/sdk/db/id.py | 6 ++ skyvern/forge/sdk/db/models.py | 32 +++++++++++ 3 files changed, 94 insertions(+) create mode 100644 alembic/versions/2025_08_06_1946-2fe3e908a028_add_workflow_scripts_table.py diff --git a/alembic/versions/2025_08_06_1946-2fe3e908a028_add_workflow_scripts_table.py b/alembic/versions/2025_08_06_1946-2fe3e908a028_add_workflow_scripts_table.py new file mode 100644 index 00000000..a1008c31 --- /dev/null +++ b/alembic/versions/2025_08_06_1946-2fe3e908a028_add_workflow_scripts_table.py @@ -0,0 +1,56 @@ +"""add workflow_scripts table + +Revision ID: 2fe3e908a028 +Revises: f2e78df26c97 +Create Date: 2025-08-06 19:46:37.998908+00:00 + +""" + +from typing import Sequence, Union + +import sqlalchemy as sa + +from alembic import op + +# revision identifiers, used by Alembic. +revision: str = "2fe3e908a028" +down_revision: Union[str, None] = "f2e78df26c97" +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.create_table( + "workflow_scripts", + sa.Column("workflow_script_id", sa.String(), nullable=False), + sa.Column("script_id", sa.String(), nullable=False), + sa.Column("organization_id", sa.String(), nullable=False), + sa.Column("workflow_permanent_id", sa.String(), nullable=False), + sa.Column("workflow_id", sa.String(), nullable=True), + sa.Column("workflow_run_id", sa.String(), nullable=True), + sa.Column("cache_key", sa.String(), nullable=False), + sa.Column("cache_key_value", sa.String(), nullable=False), + sa.Column("created_at", sa.DateTime(), nullable=False), + sa.Column("modified_at", sa.DateTime(), nullable=False), + sa.Column("deleted_at", sa.DateTime(), nullable=True), + sa.PrimaryKeyConstraint("workflow_script_id"), + sa.UniqueConstraint( + "workflow_permanent_id", "cache_key_value", name="uc_workflow_permanent_id_cache_key_value" + ), + ) + op.create_index( + "idx_workflow_scripts_org_created", "workflow_scripts", ["organization_id", "created_at"], unique=False + ) + op.create_index( + "idx_workflow_scripts_workflow_permanent_id", "workflow_scripts", ["workflow_permanent_id"], unique=False + ) + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index("idx_workflow_scripts_workflow_permanent_id", table_name="workflow_scripts") + op.drop_index("idx_workflow_scripts_org_created", table_name="workflow_scripts") + op.drop_table("workflow_scripts") + # ### end Alembic commands ### diff --git a/skyvern/forge/sdk/db/id.py b/skyvern/forge/sdk/db/id.py index 42840b5a..51a0e15a 100644 --- a/skyvern/forge/sdk/db/id.py +++ b/skyvern/forge/sdk/db/id.py @@ -59,6 +59,7 @@ WORKFLOW_PERMANENT_ID_PREFIX = "wpid" WORKFLOW_PREFIX = "w" WORKFLOW_RUN_BLOCK_PREFIX = "wrb" WORKFLOW_RUN_PREFIX = "wr" +WORKFLOW_SCRIPT_PREFIX = "ws" def generate_workflow_id() -> str: @@ -81,6 +82,11 @@ def generate_workflow_run_id() -> str: return f"{WORKFLOW_RUN_PREFIX}_{int_id}" +def generate_workflow_script_id() -> str: + int_id = generate_id() + return f"{WORKFLOW_SCRIPT_PREFIX}_{int_id}" + + def generate_aws_secret_parameter_id() -> str: int_id = generate_id() return f"{AWS_SECRET_PARAMETER_PREFIX}_{int_id}" diff --git a/skyvern/forge/sdk/db/models.py b/skyvern/forge/sdk/db/models.py index 3b23fdac..99cce713 100644 --- a/skyvern/forge/sdk/db/models.py +++ b/skyvern/forge/sdk/db/models.py @@ -50,6 +50,7 @@ from skyvern.forge.sdk.db.id import ( generate_workflow_permanent_id, generate_workflow_run_block_id, generate_workflow_run_id, + generate_workflow_script_id, ) from skyvern.forge.sdk.schemas.task_v2 import ThoughtType @@ -828,3 +829,34 @@ class ProjectFileModel(Base): created_at = Column(DateTime, default=datetime.datetime.utcnow, nullable=False) modified_at = Column(DateTime, default=datetime.datetime.utcnow, onupdate=datetime.datetime.utcnow, nullable=False) deleted_at = Column(DateTime, nullable=True) + + +class WorkflowScriptModel(Base): + __tablename__ = "workflow_scripts" + __table_args__ = ( + UniqueConstraint( + "workflow_permanent_id", + "cache_key_value", + name="uc_workflow_permanent_id_cache_key_value", + ), + Index("idx_workflow_scripts_org_created", "organization_id", "created_at"), + Index("idx_workflow_scripts_workflow_permanent_id", "workflow_permanent_id"), + ) + + workflow_script_id = Column(String, primary_key=True, default=generate_workflow_script_id) + script_id = Column(String, nullable=False) + organization_id = Column(String, nullable=False) + workflow_permanent_id = Column(String, nullable=False) + workflow_id = Column(String, nullable=True) + workflow_run_id = Column(String, nullable=True) + cache_key = Column(String, nullable=False) # e.g. "test-{{ website_url }}-cache" + cache_key_value = Column(String, nullable=False) # e.g. "test-greenhouse.io/job/1-cache" + + created_at = Column(DateTime, default=datetime.datetime.utcnow, nullable=False) + modified_at = Column( + DateTime, + default=datetime.datetime.utcnow, + onupdate=datetime.datetime.utcnow, + nullable=False, + ) + deleted_at = Column(DateTime, nullable=True)