Skip to content

Commit f88a67c

Browse files
committed
feat: add workflow code
1 parent 6045c5f commit f88a67c

File tree

223 files changed

+13182
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

223 files changed

+13182
-0
lines changed

.gitignore

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
.turbo
2+
node_modules
3+
dist
4+
.next
5+
.env
6+
.dev.vars
7+
.vercel
8+
.DS_Store
9+
.idea
10+
11+
# examples
12+
examples/*/package-lock.json
13+
examples/*/pnpm-lock.yaml
14+
examples/ngrok.log
15+
restart.sh
16+
17+
bootstrap.sh

.husky/commit-msg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
bun --no -- commitlint --edit ""

.husky/pre-commit

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
bun run lint && bun run fmt

.husky/pre-push

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
bun run test && bun run build

.prettierignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
dist
2+
examples
3+
node_modules

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2024 Upstash, Inc.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

bun.lockb

326 KB
Binary file not shown.

commitlint.config.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
2+
// ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
3+
// docs: Documentation only changes
4+
// feat: A new feature
5+
// fix: A bug fix
6+
// perf: A code change that improves performance
7+
// refactor: A code change that neither fixes a bug nor adds a feature
8+
// style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
9+
// test: Adding missing tests or correcting existing tests
10+
11+
module.exports = {
12+
extends: ["@commitlint/config-conventional"],
13+
rules: {
14+
"body-leading-blank": [1, "always"],
15+
"body-max-line-length": [2, "always", 100],
16+
"footer-leading-blank": [1, "always"],
17+
"footer-max-line-length": [2, "always", 100],
18+
"header-max-length": [2, "always", 100],
19+
"scope-case": [2, "always", "lower-case"],
20+
"subject-case": [2, "never", ["sentence-case", "start-case", "pascal-case", "upper-case"]],
21+
"subject-empty": [2, "never"],
22+
"subject-full-stop": [2, "never", "."],
23+
"type-case": [2, "always", "lower-case"],
24+
"type-empty": [2, "never"],
25+
"type-enum": [
26+
2,
27+
"always",
28+
[
29+
"build",
30+
"chore",
31+
"ci",
32+
"docs",
33+
"feat",
34+
"fix",
35+
"perf",
36+
"refactor",
37+
"revert",
38+
"style",
39+
"test",
40+
"translation",
41+
"security",
42+
"changeset",
43+
],
44+
],
45+
},
46+
};

eslint.config.mjs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import globals from "globals";
2+
import pluginJs from "@eslint/js";
3+
import tseslint from "typescript-eslint";
4+
5+
export default [
6+
{ files: ["**/*.{js,mjs,cjs,ts}"] },
7+
{ languageOptions: { globals: globals.browser } },
8+
pluginJs.configs.recommended,
9+
...tseslint.configs.recommended,
10+
];

examples/README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Workflow Examples
2+
3+
This directory has example projects for Upstash Workflows with different frameworks.
4+
5+
Each project has an interface where you can enter the deployment URL, pick a workflow endpoint, enter a payload and finally call the picked workflow endpoint.
6+
7+
## How to Run
8+
9+
There are three alternatives:
10+
1. Deploy the app and use the interface to call it
11+
2. Run the app locally and create a local tunnel with Ngrok so that QStash can call it. Doing this is simplified through the `bootstrap.sh` script.
12+
3. If you have access to the QStash development server, run both the development server and the example workflow project locally. Unfortunetly, local QStash development server is not public.
13+
14+
### `bootstrap.sh` Script
15+
16+
First, set the environment variables `QSTASH_TOKEN`, `QSTASH_URL`, `QSTASH_CURRENT_SIGNING_KEY` and `QSTASH_NEXT_SIGNING_KEY`.
17+
18+
The `bootstrap.sh` script makes it possible to start an examplew workflow project and create a Ngrok tunnel in one script. To run it, simply choose the framework and the endpoint you would like to choose as default:
19+
20+
```
21+
bash bootstrap.sh <example-framework>
22+
```
23+
24+
Here is an example call:
25+
26+
```
27+
bash bootstrap.sh nextjs
28+
```
29+
30+
Here is what the script does in a nutshell:
31+
- create a Ngrok tunnel from `localhost:3001`
32+
- Public URL of the tunnel is inferred from Ngrok logs. This URL is set to the `UPSTASH_WORKFLOW_URL` environment variable.
33+
- `npm install` and `npm run dev` are executed in the example directory
34+
- a web browser is opened with the picked endpoint
35+
36+
To use the app, simply send a request through the opened interface.
37+
38+
You will be able to see the workflow executing in the console logs. You can also monitor the events in [the QStash tab of Upstash Console](https://console.upstash.com/qstash?tab=workflow).
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
QSTASH_URL=
2+
QSTASH_TOKEN=
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Deploy Worker
2+
on:
3+
push:
4+
pull_request:
5+
repository_dispatch:
6+
jobs:
7+
deploy:
8+
runs-on: ubuntu-latest
9+
timeout-minutes: 60
10+
steps:
11+
- uses: actions/checkout@v2
12+
- name: Build & Deploy Worker
13+
uses: cloudflare/wrangler-action@v3
14+
with:
15+
apiToken: ${{ secrets.CF_API_TOKEN }}
16+
accountId: ${{ secrets.CF_ACCOUNT_ID }}
17+
env:
18+
QSTASH_URL: ${{ secrets.QSTASH_URL }}
19+
QSTASH_TOKEN: ${{ secrets.QSTASH_TOKEN }}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/.dev.vars
2+
/.wrangler/
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Upstash Workflow Cloudflare Workers Example (with Hono)
2+
3+
This is an example of how to use Upstash Workflow with Cloudflare Workers with Hono router. You can learn more in [Workflow documentation for Hono](https://upstash.com/docs/qstash/workflow/quickstarts/hono).
4+
5+
[![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/upstash/qstash-workflow-example-cloudflare-workers-hono) <br/>
6+
**Note:** After deploying with the button above, you need to set the environment variables `QSTASH_URL` and `QSTASH_TOKEN`.
7+
8+
## Development
9+
10+
> [!TIP]
11+
> You can use [the `bootstrap.sh` script](https://github.com/upstash/qstash-js/tree/main/examples/workflow) to run this example with a local tunnel.
12+
>
13+
> Simply set the environment variables as explained below and run the following command in the `qstash-js/examples/workflow` directory:
14+
>
15+
> ```
16+
> bash bootstrap.sh cloudflare-workers-hono
17+
> ```
18+
19+
1. Install the dependencies
20+
21+
```bash
22+
npm install
23+
```
24+
25+
2. Get the credentials from the [Upstash Console](https://console.upstash.com/qstash) and add them to the `.dev.vars` file.
26+
27+
```bash
28+
QSTASH_URL=
29+
QSTASH_TOKEN=
30+
```
31+
32+
3. Open a local tunnel to port of the development server
33+
34+
```bash
35+
ngrok http 3001
36+
```
37+
38+
Also, set the `UPSTASH_WORKLFOW_URL` environment variable to the public url provided by ngrok.
39+
40+
4. Run the development server
41+
42+
```bash
43+
npm run dev
44+
```
45+
46+
5. Send a `POST` request to the `/workflow` endpoint.
47+
48+
```bash
49+
curl -X POST "http://localhost:3001/workflow" -d '{"text": "hello world!"}'
50+
```
51+
52+
## Deployment
53+
54+
You can use wrangler to deploy the project to Cloudflare Workers.
55+
56+
```bash
57+
npm run deploy
58+
```
59+
60+
Then, go to cloudflare dashboard and find your project. Add the
61+
`QSTASH_TOKEN` environment variable and re-deploy the project.
62+
63+
Once the project is re-deployed, you can send a curl request
64+
like the one above (after replacing the localhost with the
65+
deployment URL).
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "cloudflare-workers",
3+
"version": "0.0.0",
4+
"dependencies": {
5+
"@upstash/qstash": "latest",
6+
"hono": "^4.5.8"
7+
},
8+
"devDependencies": {
9+
"@cloudflare/workers-types": "^4.20240815.0",
10+
"typescript": "^5.5.2",
11+
"vitest": "1.5.0",
12+
"wrangler": "^3.60.3"
13+
},
14+
"private": true,
15+
"scripts": {
16+
"dev": "wrangler dev --port 3001 --var UPSTASH_WORKFLOW_URL:$UPSTASH_WORKFLOW_URL",
17+
"deploy": "wrangler publish"
18+
}
19+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Hono } from "hono";
2+
import { serve, WorkflowBindings } from "@upstash/qstash/hono";
3+
import { landingPage } from "./page";
4+
5+
const app = new Hono<{ Bindings: WorkflowBindings }>();
6+
7+
app.get("/", (c) => {
8+
return c.html(landingPage);
9+
});
10+
11+
const someWork = (input: string) => {
12+
return `processed '${JSON.stringify(input)}'`;
13+
};
14+
15+
app.post(
16+
"/workflow",
17+
serve<{ text: string }>(
18+
async (context) => {
19+
const input = context.requestPayload.text;
20+
const result1 = await context.run("step1", async () => {
21+
const output = someWork(input);
22+
console.log("step 1 input", input, "output", output);
23+
return output;
24+
});
25+
26+
const result2 = await context.run("step2", async () => {
27+
const output = someWork(result1);
28+
console.log("step 2 input", result1, "output", output);
29+
});
30+
},
31+
{
32+
receiver: undefined,
33+
},
34+
),
35+
);
36+
37+
export default app;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import app from "./app";
2+
3+
export type Env = {
4+
QSTASH_URL: string;
5+
QSTASH_TOKEN: string;
6+
QSTASH_CURRENT_SIGNING_KEY: string;
7+
QSTASH_NEXT_SIGNING_KEY: string;
8+
};
9+
10+
export default app;

0 commit comments

Comments
 (0)