{"id":29117223,"url":"https://github.com/luno/workflow","last_synced_at":"2025-12-12T17:04:00.037Z","repository":{"id":217790402,"uuid":"743635938","full_name":"luno/workflow","owner":"luno","description":"A tech stack agnostic Event Driven Workflow framework, written in Go, that supports durable, robust, and idempotent state changes with timeouts, callbacks, scheduled triggers, and await calls. Compatible with Kafka and Reflex out of the box.","archived":false,"fork":false,"pushed_at":"2025-06-11T20:35:31.000Z","size":1316,"stargazers_count":165,"open_issues_count":4,"forks_count":10,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-06-11T21:53:52.224Z","etag":null,"topics":["durable","eda","eventdrivenarchitecture","go","golang","hacktoberfest","idempotent","kafka","reflex","state-machine","statemachine","tdd","workflow","workflow-automation","workflow-engine","workflows"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/luno.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-01-15T16:54:00.000Z","updated_at":"2025-06-11T20:34:12.000Z","dependencies_parsed_at":"2024-05-14T10:48:17.921Z","dependency_job_id":"1942e708-17b9-4a8f-9b59-260f189e9121","html_url":"https://github.com/luno/workflow","commit_stats":null,"previous_names":["luno/workflow"],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/luno/workflow","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luno%2Fworkflow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luno%2Fworkflow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luno%2Fworkflow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luno%2Fworkflow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/luno","download_url":"https://codeload.github.com/luno/workflow/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luno%2Fworkflow/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262581514,"owners_count":23331925,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["durable","eda","eventdrivenarchitecture","go","golang","hacktoberfest","idempotent","kafka","reflex","state-machine","statemachine","tdd","workflow","workflow-automation","workflow-engine","workflows"],"created_at":"2025-06-29T11:14:17.766Z","updated_at":"2025-12-12T17:04:00.027Z","avatar_url":"https://github.com/luno.png","language":"Go","readme":"\u003cdiv align=\"center\"\u003e\n    \u003cimg src=\"./logo/logo.png\" style=\"width: 220px; margin: 30px\" alt=\"Workflow Logo\"\u003e\n    \u003cdiv  align=\"center\" style=\"max-width: 750px\"\u003e\n        \u003ca style=\"padding: 0 5px\" href=\"https://goreportcard.com/report/github.com/luno/workflow\"\u003e\u003cimg src=\"https://goreportcard.com/badge/github.com/luno/workflow\"/\u003e\u003c/a\u003e\n        \u003ca style=\"padding: 0 5px\" href=\"https://sonarcloud.io/summary/new_code?id=luno_workflow\"\u003e\u003cimg src=\"https://sonarcloud.io/api/project_badges/measure?project=luno_workflow\u0026metric=coverage\"/\u003e\u003c/a\u003e\n        \u003ca style=\"padding: 0 5px\" href=\"https://sonarcloud.io/summary/new_code?id=luno_workflow\"\u003e\u003cimg src=\"https://sonarcloud.io/api/project_badges/measure?project=luno_workflow\u0026metric=alert_status\"/\u003e\u003c/a\u003e\n        \u003ca style=\"padding: 0 5px\" href=\"https://sonarcloud.io/summary/new_code?id=luno_workflow\"\u003e\u003cimg src=\"https://sonarcloud.io/api/project_badges/measure?project=luno_workflow\u0026metric=bugs\"/\u003e\u003c/a\u003e\n        \u003ca style=\"padding: 0 5px\" href=\"https://sonarcloud.io/summary/new_code?id=luno_workflow\"\u003e\u003cimg src=\"https://sonarcloud.io/api/project_badges/measure?project=luno_workflow\u0026metric=reliability_rating\"/\u003e\u003c/a\u003e\u003ca style=\"text-decoration:none; padding: 0 5px\" href=\"https://sonarcloud.io/summary/new_code?id=luno_workflow\" \u003e\u003cimg src=\"https://sonarcloud.io/api/project_badges/measure?project=luno_workflow\u0026metric=security_rating\"/\u003e\u003c/a\u003e\n        \u003ca style=\"padding: 0 5px\" href=\"https://sonarcloud.io/summary/new_code?id=luno_workflow\"\u003e\u003cimg src=\"https://sonarcloud.io/api/project_badges/measure?project=luno_workflow\u0026metric=sqale_rating\"/\u003e\u003c/a\u003e\n        \u003ca style=\"padding: 0 5px\" href=\"https://sonarcloud.io/summary/new_code?id=luno_workflow\"\u003e\u003cimg src=\"https://sonarcloud.io/api/project_badges/measure?project=luno_workflow\u0026metric=vulnerabilities\"/\u003e\u003c/a\u003e\n        \u003ca style=\"padding: 0 5px\" href=\"https://sonarcloud.io/summary/new_code?id=luno_workflow\"\u003e\u003cimg src=\"https://sonarcloud.io/api/project_badges/measure?project=luno_workflow\u0026metric=duplicated_lines_density\"/\u003e\u003c/a\u003e\n        \u003ca style=\"padding: 0 5px\" href=\"https://pkg.go.dev/github.com/luno/workflow\"\u003e\u003cimg src=\"https://pkg.go.dev/badge/github.com/luno/workflow.svg\" alt=\"Go Reference\"\u003e\u003c/a\u003e\n        \u003ca style=\"padding: 0 5px\" href=\"https://github.com/avelino/awesome-go\"\u003e\u003cimg src=\"https://awesome.re/mentioned-badge-flat.svg\" alt=\"Mentioned in Awesome Go\"\u003e\u003c/a\u003e\n    \u003c/div\u003e\n\u003c/div\u003e\n\n# Workflow\n\n**The type-safe, event-driven workflow orchestration library that scales with your business.**\n\nBuild robust, distributed workflows in Go with compile-time safety, automatic retries, and horizontal scaling out of the box.\n\n```go\n// Define your business logic as type-safe state machines\nb := workflow.NewBuilder[Order, OrderStatus](\"order-processing\")\nb.AddStep(OrderCreated, ProcessPayment, PaymentProcessed)\nb.AddStep(PaymentProcessed, FulfillOrder, OrderCompleted)\n\nwf := b.Build(kafkaStreamer, sqlStore, roleScheduler)\n```\n\n## Why Choose Workflow?\n\n### 🎯 **Type-Safe by Design**\nUnlike other orchestrators, Workflow leverages Go generics for **compile-time guarantees**. Catch errors before deployment, not in production.\n\n```go\n// Your IDE knows exactly what data flows where\nfunc processPayment(ctx context.Context, r *workflow.Run[Order, OrderStatus]) (OrderStatus, error) {\n    // r.Object is typed as *Order, OrderStatus is your enum\n    // Compiler catches mismatches before they cause runtime errors\n}\n```\n\n### ⚡ **Event-Driven Architecture**\nBuilt for modern distributed systems. Steps communicate through durable events, enabling:\n- **Loose coupling** between workflow components\n- **Automatic retries** with exponential backoff\n- **Horizontal scaling** across multiple instances\n- **Fault tolerance** that survives network partitions\n\n### 🔧 **Infrastructure Agnostic**\nYour choice of database, message queue, and coordination service. Start simple, scale when needed:\n\n```go\n// Development: Everything in-memory\nwf := b.Build(memstreamer.New(), memrecordstore.New(), memrolescheduler.New())\n\n// Production: Battle-tested infrastructure\nwf := b.Build(kafkastreamer.New(), sqlstore.New(), rinkrolescheduler.New())\n```\n\n### 📊 **Built-in Observability**\nProduction-ready monitoring without the setup overhead:\n- **Prometheus metrics** for throughput, latency, and error rates\n- **Web UI** for real-time workflow visualization\n- **Structured logging** with correlation IDs\n- **Distributed tracing** support\n\n## Perfect For\n\n- **Order Processing**: Payment, inventory, fulfillment pipelines\n- **User Onboarding**: Multi-step verification and activation flows\n- **Financial Operations**: Transaction processing with compliance checks\n- **Data Processing**: ETL pipelines with validation and cleanup\n- **Approval Workflows**: Multi-stakeholder review processes\n\n## vs. The Alternatives\n\n| Feature | **Workflow** | Temporal | Zeebe/Camunda |\n|---------|-------------|----------|---------------|\n| **Type Safety** | ✅ Compile-time (Go generics) | ❌ Runtime validation | ❌ Runtime (BPMN) |\n| **Architecture** | ✅ Event-driven state machines | ⚠️ RPC-based activities | ⚠️ Token-based execution |\n| **Infrastructure** | ✅ Your choice (adapters) | ❌ Requires Temporal cluster | ❌ Requires external engine |\n| **Deployment** | ✅ Library in your app | ❌ Separate server/workers | ❌ Separate engine |\n| **Learning Curve** | ✅ Native Go patterns | ⚠️ New concepts \u0026 SDKs | ❌ BPMN modeling |\n| **Language** | ✅ Go-native | ⚠️ Multi-language via gRPC | ⚠️ Multi-language |\n\n## Quick Start\n\n```bash\ngo get github.com/luno/workflow\n```\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"github.com/luno/workflow\"\n    \"github.com/luno/workflow/adapters/memstreamer\"\n    \"github.com/luno/workflow/adapters/memrecordstore\"\n    \"github.com/luno/workflow/adapters/memrolescheduler\"\n)\n\ntype TaskStatus int\nconst (\n    TaskStatusUnknown   TaskStatus = 0\n    TaskStatusCreated   TaskStatus = 1\n    TaskStatusProcessed TaskStatus = 2\n    TaskStatusCompleted TaskStatus = 3\n)\n\ntype Task struct {\n    ID   string\n    Name string\n}\n\nfunc main() {\n    b := workflow.NewBuilder[Task, TaskStatus](\"task-processor\")\n\n    b.AddStep(TaskStatusCreated, func(ctx context.Context, r *workflow.Run[Task, TaskStatus]) (TaskStatus, error) {\n        fmt.Printf(\"Processing: %s\\n\", r.Object.Name)\n        return TaskStatusProcessed, nil\n    }, TaskStatusProcessed)\n\n    b.AddStep(TaskStatusProcessed, func(ctx context.Context, r *workflow.Run[Task, TaskStatus]) (TaskStatus, error) {\n        fmt.Printf(\"Completed: %s\\n\", r.Object.Name)\n        return TaskStatusCompleted, nil\n    }, TaskStatusCompleted)\n\n    wf := b.Build(memstreamer.New(), memrecordstore.New(), memrolescheduler.New())\n\n    ctx := context.Background()\n    wf.Run(ctx)\n    defer wf.Stop()\n\n    // Trigger a workflow\n    runID, _ := wf.Trigger(ctx, \"task-1\", workflow.WithInitialValue(\u0026Task{\n        ID: \"task-1\",\n        Name: \"Process Invoice\",\n    }))\n\n    // Wait for completion\n    wf.Await(ctx, \"task-1\", runID, TaskStatusCompleted)\n    fmt.Println(\"✅ Workflow completed!\")\n}\n```\n\n## Enterprise Ready\n\n**Workflow** provides enterprise-grade features:\n\n- ✅ **Exactly-once processing** guarantees via transactional outbox pattern\n- ✅ **Built-in error handling** with pause and retry mechanisms\n- ✅ **Comprehensive observability** via Prometheus metrics and Web UI\n- ✅ **Horizontal scaling** through role-based scheduling\n- ✅ **Infrastructure flexibility** via pluggable adapters\n- ✅ **Production deployment** patterns for various scales\n\n## Documentation\n\n| Topic | Description |\n|-------|-------------|\n| **[Getting Started](docs/getting-started.md)** | Install and build your first workflow |\n| **[Core Concepts](docs/concepts.md)** | Understand Runs, Events, and State Machines |\n| **[Architecture](docs/architecture.md)** | Deep dive into system design and components |\n| **[Steps](docs/steps.md)** | Build workflow logic with step functions |\n| **[Callbacks](docs/callbacks.md)** | Handle external events and webhooks |\n| **[Timeouts](docs/timeouts.md)** | Add time-based operations |\n| **[Connectors](docs/connectors.md)** | Integrate with external event streams |\n| **[Hooks](docs/hooks.md)** | React to workflow lifecycle changes |\n| **[Configuration](docs/configuration.md)** | Tune performance and behavior |\n| **[Monitoring](docs/monitoring.md)** | Observability and debugging |\n| **[Adapters](docs/adapters.md)** | Infrastructure integration guide |\n\n### Examples \u0026 Tutorials\n\n| Example | Description |\n|---------|-------------|\n| **[Order Processing](docs/examples/order-processing.go)** | Complete e-commerce workflow with payments \u0026 fulfillment |\n\n\n## Community \u0026 Support\n\n- 📚 **[Documentation](docs/)** - Comprehensive guides and examples\n- 🐛 **[Issues](https://github.com/luno/workflow/issues)** - Bug reports and feature requests\n- 💬 **[Discussions](https://github.com/luno/workflow/discussions)** - Community Q\u0026A\n\n## Installation\n\n```bash\ngo get github.com/luno/workflow\n\n# Production adapters (install as needed)\ngo get github.com/luno/workflow/adapters/kafkastreamer\ngo get github.com/luno/workflow/adapters/sqlstore\ngo get github.com/luno/workflow/adapters/rinkrolescheduler\ngo get github.com/luno/workflow/adapters/webui\n```\n\n## License\n\n[MIT License](LICENSE)\n\n---\n\n**Ready to build reliable workflows?** [Get started in 5 minutes →](docs/getting-started.md)","funding_links":[],"categories":["Workflow Frameworks"],"sub_categories":["Routers","Utility/Miscellaneous","路由器"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fluno%2Fworkflow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fluno%2Fworkflow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fluno%2Fworkflow/lists"}