From 0dd3447c3174cf3847857dc34c1cafae6626efbd Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Sat, 25 May 2024 12:11:36 +0100 Subject: [PATCH 1/3] Improved the migration from v2 to v3 guide --- docs/v3/upgrading-from-v2.mdx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/v3/upgrading-from-v2.mdx b/docs/v3/upgrading-from-v2.mdx index 012c8c481..3a687f776 100644 --- a/docs/v3/upgrading-from-v2.mdx +++ b/docs/v3/upgrading-from-v2.mdx @@ -171,10 +171,16 @@ async function yourBackendFunction() { ## Upgrading your project -Just follow the [v3 quick start](/v3/quick-start) to get started with v3. Our new CLI will take care of the rest. +1. Make sure to upgrade all of your trigger.dev packages to v3 first. + +```bash +npx @trigger.dev/cli@beta update --to beta +``` + +2. Follow the [v3 quick start](/v3/quick-start) to get started with v3. Our new CLI will take care of the rest. ## Using v2 together with v3 You can use v2 and v3 in the same codebase. This can be useful where you already have v2 jobs or where we don't support features you need (yet). - +We do not support calling v3 tasks from v2 jobs or vice versa. From b6de469d07954e44302b98452b1ca111255ea51f Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 28 May 2024 12:09:05 +0100 Subject: [PATCH 2/3] Proxy rate limit (#1131) * Updated worker types * Cloudflare rate limiter applied to sendEvent/sendEvents * Latest wrangler * Updated to the latest compatibility_date and nest the unsafe bindings properly * Added some types from a Discord members * Better logging and added a reset header so the SDK can use it from inside the run function * Set staging proxy rate limit to 100/60s --- apps/proxy/package.json | 4 +- apps/proxy/src/index.ts | 8 +- apps/proxy/src/rateLimit.ts | 46 +++++++ apps/proxy/src/rateLimiter.ts | 23 ++++ apps/proxy/wrangler.toml | 30 +++- pnpm-lock.yaml | 249 +++++++++++++++++++++++++--------- 6 files changed, 290 insertions(+), 70 deletions(-) create mode 100644 apps/proxy/src/rateLimit.ts create mode 100644 apps/proxy/src/rateLimiter.ts diff --git a/apps/proxy/package.json b/apps/proxy/package.json index 84f70924e..15ed6ae0e 100644 --- a/apps/proxy/package.json +++ b/apps/proxy/package.json @@ -7,9 +7,9 @@ "dev": "wrangler dev" }, "devDependencies": { - "@cloudflare/workers-types": "^4.20230419.0", + "@cloudflare/workers-types": "^4.20240512.0", "typescript": "^5.0.4", - "wrangler": "^3.0.0" + "wrangler": "^3.57.1" }, "dependencies": { "@aws-sdk/client-sqs": "^3.445.0", diff --git a/apps/proxy/src/index.ts b/apps/proxy/src/index.ts index b6db2f60f..e8cf12892 100644 --- a/apps/proxy/src/index.ts +++ b/apps/proxy/src/index.ts @@ -1,5 +1,7 @@ import { queueEvent } from "./events/queueEvent"; import { queueEvents } from "./events/queueEvents"; +import { applyRateLimit } from "./rateLimit"; +import { Ratelimit } from "./rateLimiter"; export interface Env { /** The hostname needs to be changed to allow requests to pass to the Trigger.dev platform */ @@ -9,6 +11,8 @@ export interface Env { AWS_SQS_SECRET_ACCESS_KEY: string; AWS_SQS_QUEUE_URL: string; AWS_SQS_REGION: string; + //rate limiter + API_RATE_LIMITER: Ratelimit; } export default { @@ -25,13 +29,13 @@ export default { switch (url.pathname) { case "/api/v1/events": { if (request.method === "POST") { - return queueEvent(request, env); + return applyRateLimit(request, env, () => queueEvent(request, env)); } break; } case "/api/v1/events/bulk": { if (request.method === "POST") { - return queueEvents(request, env); + return applyRateLimit(request, env, () => queueEvents(request, env)); } break; } diff --git a/apps/proxy/src/rateLimit.ts b/apps/proxy/src/rateLimit.ts new file mode 100644 index 000000000..ccbd7b433 --- /dev/null +++ b/apps/proxy/src/rateLimit.ts @@ -0,0 +1,46 @@ +import { Env } from "src"; +import { getApiKeyFromRequest } from "./apikey"; +import { json } from "./json"; + +export async function applyRateLimit( + request: Request, + env: Env, + fn: () => Promise +): Promise { + const apiKey = getApiKeyFromRequest(request); + if (apiKey) { + const result = await env.API_RATE_LIMITER.limit({ key: `apikey-${apiKey.apiKey}` }); + const { success } = result; + console.log(`Rate limiter`, { + success, + key: `${apiKey.apiKey.substring(0, 12)}...`, + }); + if (!success) { + //60s in the future + const reset = Date.now() + 60 * 1000; + const secondsUntilReset = Math.max(0, (reset - new Date().getTime()) / 1000); + + return json( + { + title: "Rate Limit Exceeded", + status: 429, + type: "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429", + detail: `Rate limit exceeded. Retry in ${secondsUntilReset} seconds.`, + error: `Rate limit exceeded. Retry in ${secondsUntilReset} seconds.`, + reset, + }, + { + status: 429, + headers: { + "x-ratelimit-reset": reset.toString(), + }, + } + ); + } + } else { + console.log(`Rate limiter: no API key for request`); + } + + //call the original function + return fn(); +} diff --git a/apps/proxy/src/rateLimiter.ts b/apps/proxy/src/rateLimiter.ts new file mode 100644 index 000000000..414332343 --- /dev/null +++ b/apps/proxy/src/rateLimiter.ts @@ -0,0 +1,23 @@ +export interface Ratelimit { + /* + * The ratelimit function + * @param {RatelimitOptions} options + * @returns {Promise} + */ + limit: (options: RatelimitOptions) => Promise; +} + +export interface RatelimitOptions { + /* + * The key to identify the user, can be an IP address, user ID, etc. + */ + key: string; +} + +export interface RatelimitResponse { + /* + * The ratelimit success status + * @returns {boolean} + */ + success: boolean; +} diff --git a/apps/proxy/wrangler.toml b/apps/proxy/wrangler.toml index 930f0de83..3cbfb66cd 100644 --- a/apps/proxy/wrangler.toml +++ b/apps/proxy/wrangler.toml @@ -1,7 +1,33 @@ name = "proxy" main = "src/index.ts" -compatibility_date = "2023-10-30" +compatibility_date = "2024-05-13" compatibility_flags = [ "nodejs_compat" ] [env.staging] -[env.prod] \ No newline at end of file + # The rate limiting API is in open beta. + [[env.staging.unsafe.bindings]] + name = "API_RATE_LIMITER" + type = "ratelimit" + # An identifier you define, that is unique to your Cloudflare account. + # Must be an integer. + namespace_id = "1" + + # Limit: the number of tokens allowed within a given period in a single + # Cloudflare location + # Period: the duration of the period, in seconds. Must be either 10 or 60 + simple = { limit = 100, period = 60 } + + +[env.prod] + # The rate limiting API is in open beta. + [[env.prod.unsafe.bindings]] + name = "API_RATE_LIMITER" + type = "ratelimit" + # An identifier you define, that is unique to your Cloudflare account. + # Must be an integer. + namespace_id = "2" + + # Limit: the number of tokens allowed within a given period in a single + # Cloudflare location + # Period: the duration of the period, in seconds. Must be either 10 or 60 + simple = { limit = 300, period = 60 } \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f99275a30..34fffc59e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -190,14 +190,14 @@ importers: version: 1.5.0 devDependencies: '@cloudflare/workers-types': - specifier: ^4.20230419.0 - version: 4.20231121.0 + specifier: ^4.20240512.0 + version: 4.20240512.0 typescript: specifier: ^5.0.4 version: 5.2.2 wrangler: - specifier: ^3.0.0 - version: 3.17.1 + specifier: ^3.57.1 + version: 3.57.1(@cloudflare/workers-types@4.20240512.0) apps/webapp: dependencies: @@ -5610,6 +5610,13 @@ packages: mime: 3.0.0 dev: true + /@cloudflare/kv-asset-handler@0.3.2: + resolution: {integrity: sha512-EeEjMobfuJrwoctj7FA1y1KEbM0+Q1xSjobIEyie9k4haVEBB7vkDvsasw1pM3rO39mL2akxIAzLMUAtrMHZhA==} + engines: {node: '>=16.13'} + dependencies: + mime: 3.0.0 + dev: true + /@cloudflare/workerd-darwin-64@1.20231030.0: resolution: {integrity: sha512-J4PQ9utPxLya9yHdMMx3AZeC5M/6FxcoYw6jo9jbDDFTy+a4Gslqf4Im9We3aeOEdPXa3tgQHVQOSelJSZLhIw==} engines: {node: '>=16'} @@ -5619,6 +5626,15 @@ packages: dev: true optional: true + /@cloudflare/workerd-darwin-64@1.20240512.0: + resolution: {integrity: sha512-VMp+CsSHFALQiBzPdQ5dDI4T1qwLu0mQ0aeKVNDosXjueN0f3zj/lf+mFil5/9jBbG3t4mG0y+6MMnalP9Lobw==} + engines: {node: '>=16'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@cloudflare/workerd-darwin-arm64@1.20231030.0: resolution: {integrity: sha512-WSJJjm11Del4hSneiNB7wTXGtBXI4QMCH9l5qf4iT5PAW8cESGcCmdHtWDWDtGAAGcvmLT04KNvmum92vRKKQQ==} engines: {node: '>=16'} @@ -5628,6 +5644,15 @@ packages: dev: true optional: true + /@cloudflare/workerd-darwin-arm64@1.20240512.0: + resolution: {integrity: sha512-lZktXGmzMrB5rJqY9+PmnNfv1HKlj/YLZwMjPfF0WVKHUFdvQbAHsi7NlKv6mW9uIvlZnS+K4sIkWc0MDXcRnA==} + engines: {node: '>=16'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@cloudflare/workerd-linux-64@1.20231030.0: resolution: {integrity: sha512-2HUeRTvoCC17fxE0qdBeR7J9dO8j4A8ZbdcvY8pZxdk+zERU6+N03RTbk/dQMU488PwiDvcC3zZqS4gwLfVT8g==} engines: {node: '>=16'} @@ -5637,6 +5662,15 @@ packages: dev: true optional: true + /@cloudflare/workerd-linux-64@1.20240512.0: + resolution: {integrity: sha512-wrHvqCZZqXz6Y3MUTn/9pQNsvaoNjbJpuA6vcXsXu8iCzJi911iVW2WUEBX+MpUWD+mBIP0oXni5tTlhkokOPw==} + engines: {node: '>=16'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@cloudflare/workerd-linux-arm64@1.20231030.0: resolution: {integrity: sha512-4/GK5zHh+9JbUI6Z5xTCM0ZmpKKHk7vu9thmHjUxtz+o8Ne9DoD7DlDvXQWgMF6XGaTubDWyp3ttn+Qv8jDFuQ==} engines: {node: '>=16'} @@ -5646,6 +5680,15 @@ packages: dev: true optional: true + /@cloudflare/workerd-linux-arm64@1.20240512.0: + resolution: {integrity: sha512-YPezHMySL9J9tFdzxz390eBswQ//QJNYcZolz9Dgvb3FEfdpK345cE/bsWbMOqw5ws2f82l388epoenghtYvAg==} + engines: {node: '>=16'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@cloudflare/workerd-windows-64@1.20231030.0: resolution: {integrity: sha512-fb/Jgj8Yqy3PO1jLhk7mTrHMkR8jklpbQFud6rL/aMAn5d6MQbaSrYOCjzkKGp0Zng8D2LIzSl+Fc0C9Sggxjg==} engines: {node: '>=16'} @@ -5655,10 +5698,23 @@ packages: dev: true optional: true + /@cloudflare/workerd-windows-64@1.20240512.0: + resolution: {integrity: sha512-SxKapDrIYSscMR7lGIp/av0l6vokjH4xQ9ACxHgXh+OdOus9azppSmjaPyw4/ePvg7yqpkaNjf9o258IxWtvKQ==} + engines: {node: '>=16'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@cloudflare/workers-types@4.20231121.0: resolution: {integrity: sha512-+kWfpCkqiepwAKXyHoE0gnkPgkLhz0/9HOBIGhHRsUvUKvhUtm3mbqqoGRWgF1qcjzrDUBbrrOq4MYHfFtc2RA==} dev: true + /@cloudflare/workers-types@4.20240512.0: + resolution: {integrity: sha512-o2yTEWg+YK/I1t/Me+dA0oarO0aCbjibp6wSeaw52DSE9tDyKJ7S+Qdyw/XsMrKn4t8kF6f/YOba+9O4MJfW9w==} + dev: true + /@codemirror/autocomplete@6.4.0(@codemirror/language@6.3.2)(@codemirror/state@6.2.0)(@codemirror/view@6.7.2)(@lezer/common@1.0.2): resolution: {integrity: sha512-HLF2PnZAm1s4kGs30EiqKMgD7XsYaQ0XJnMR0rofEWQ5t5D60SfqpDIkIh1ze5tiEbyUWm8+VJ6W1/erVvBMIA==} peerDependencies: @@ -13730,7 +13786,7 @@ packages: eslint: 8.45.0 eslint-import-resolver-node: 0.3.7 eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.59.6)(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.27.5)(eslint@8.45.0) - eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.59.6)(eslint-import-resolver-typescript@3.5.5)(eslint@8.45.0) + eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.59.6)(eslint@8.45.0) eslint-plugin-jest: 26.9.0(@typescript-eslint/eslint-plugin@5.59.6)(eslint@8.45.0)(typescript@4.9.5) eslint-plugin-jest-dom: 4.0.3(eslint@8.45.0) eslint-plugin-jsx-a11y: 6.7.1(eslint@8.45.0) @@ -16424,6 +16480,7 @@ packages: typescript: 4.9.5 transitivePeerDependencies: - supports-color + dev: true /@typescript-eslint/parser@5.59.6(eslint@8.45.0)(typescript@5.1.6): resolution: {integrity: sha512-7pCa6al03Pv1yf/dUg/s1pXz/yGMUBAw5EeWqNTFiSueKvRNonze3hma3lhdsOrQcaOXhbk5gKu2Fludiho9VA==} @@ -16443,7 +16500,6 @@ packages: typescript: 5.1.6 transitivePeerDependencies: - supports-color - dev: false /@typescript-eslint/parser@5.59.6(eslint@8.45.0)(typescript@5.2.2): resolution: {integrity: sha512-7pCa6al03Pv1yf/dUg/s1pXz/yGMUBAw5EeWqNTFiSueKvRNonze3hma3lhdsOrQcaOXhbk5gKu2Fludiho9VA==} @@ -16609,6 +16665,7 @@ packages: typescript: 4.9.5 transitivePeerDependencies: - supports-color + dev: true /@typescript-eslint/typescript-estree@5.59.6(typescript@5.0.4): resolution: {integrity: sha512-vW6JP3lMAs/Tq4KjdI/RiHaaJSO7IUsbkz17it/Rl9Q+WkQ77EOuOnlbaU8kKfVIOJxMhnRiBG+olE7f3M16DA==} @@ -16650,7 +16707,6 @@ packages: typescript: 5.1.6 transitivePeerDependencies: - supports-color - dev: false /@typescript-eslint/typescript-estree@5.59.6(typescript@5.2.2): resolution: {integrity: sha512-vW6JP3lMAs/Tq4KjdI/RiHaaJSO7IUsbkz17it/Rl9Q+WkQ77EOuOnlbaU8kKfVIOJxMhnRiBG+olE7f3M16DA==} @@ -20991,7 +21047,7 @@ packages: eslint: 8.45.0 eslint-import-resolver-node: 0.3.7 eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.59.6)(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.27.5)(eslint@8.45.0) - eslint-plugin-import: 2.27.5(eslint@8.45.0) + eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.59.6)(eslint-import-resolver-typescript@3.5.5)(eslint@8.45.0) eslint-plugin-jsx-a11y: 6.7.1(eslint@8.45.0) eslint-plugin-react: 7.32.2(eslint@8.45.0) eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.45.0) @@ -21281,7 +21337,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.59.6(eslint@8.45.0)(typescript@4.9.5) + '@typescript-eslint/parser': 5.59.6(eslint@8.45.0)(typescript@5.1.6) debug: 3.2.7(supports-color@5.5.0) eslint: 8.45.0 eslint-import-resolver-node: 0.3.7 @@ -21289,6 +21345,35 @@ packages: transitivePeerDependencies: - supports-color + /eslint-module-utils@2.7.4(@typescript-eslint/parser@5.59.6)(eslint-import-resolver-node@0.3.7)(eslint@8.45.0): + resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + '@typescript-eslint/parser': 5.59.6(eslint@8.45.0)(typescript@4.9.5) + debug: 3.2.7(supports-color@5.5.0) + eslint: 8.45.0 + eslint-import-resolver-node: 0.3.7 + transitivePeerDependencies: + - supports-color + dev: true + /eslint-plugin-es@3.0.1(eslint@8.31.0): resolution: {integrity: sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==} engines: {node: '>=8.10.0'} @@ -21398,7 +21483,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.59.6(eslint@8.45.0)(typescript@4.9.5) + '@typescript-eslint/parser': 5.59.6(eslint@8.45.0)(typescript@5.1.6) array-includes: 3.1.6 array.prototype.flat: 1.3.1 array.prototype.flatmap: 1.3.1 @@ -21420,7 +21505,7 @@ packages: - eslint-import-resolver-webpack - supports-color - /eslint-plugin-import@2.27.5(eslint@8.45.0): + /eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.59.6)(eslint@8.45.0): resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==} engines: {node: '>=4'} peerDependencies: @@ -21430,6 +21515,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: + '@typescript-eslint/parser': 5.59.6(eslint@8.45.0)(typescript@4.9.5) array-includes: 3.1.6 array.prototype.flat: 1.3.1 array.prototype.flatmap: 1.3.1 @@ -21437,7 +21523,7 @@ packages: doctrine: 2.1.0 eslint: 8.45.0 eslint-import-resolver-node: 0.3.7 - eslint-module-utils: 2.7.4(@typescript-eslint/parser@5.59.6)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.45.0) + eslint-module-utils: 2.7.4(@typescript-eslint/parser@5.59.6)(eslint-import-resolver-node@0.3.7)(eslint@8.45.0) has: 1.0.3 is-core-module: 2.13.0 is-glob: 4.0.3 @@ -21450,7 +21536,7 @@ packages: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - dev: false + dev: true /eslint-plugin-jest-dom@4.0.3(eslint@8.31.0): resolution: {integrity: sha512-9j+n8uj0+V0tmsoS7bYC7fLhQmIvjRqRYEcbDSi+TKPsTThLLXCyj5swMSSf/hTleeMktACnn+HFqXBr5gbcbA==} @@ -26964,29 +27050,6 @@ packages: hasBin: true dev: true - /miniflare@3.20231030.1: - resolution: {integrity: sha512-Y+EkgV/aFg/3Y/xfFtImK36sLZGXvNS45avVEz0cUCA2pGpg4hGdPu1Udmz5b06SyeUEFVf/dEDMJwdRYVEgLw==} - engines: {node: '>=16.13'} - hasBin: true - dependencies: - acorn: 8.10.0 - acorn-walk: 8.3.2 - capnp-ts: 0.7.0 - exit-hook: 2.2.1 - glob-to-regexp: 0.4.1 - source-map-support: 0.5.21 - stoppable: 1.1.0 - undici: 5.25.4 - workerd: 1.20231030.0 - ws: 8.16.0 - youch: 3.3.3 - zod: 3.22.4 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - dev: true - /miniflare@3.20231030.2: resolution: {integrity: sha512-+DYdMqWlUaY4wBylIjewNu8OVsPFquYjQkxoSb2jGIMBmlKaef65Hn2Bu8sub5tQzQ8tLO0FRklmD2Upx0HCCQ==} engines: {node: '>=16.13'} @@ -27033,6 +27096,29 @@ packages: - utf-8-validate dev: true + /miniflare@3.20240512.0: + resolution: {integrity: sha512-X0PlKR0AROKpxFoJNmRtCMIuJxj+ngEcyTOlEokj2rAQ0TBwUhB4/1uiPvdI6ofW5NugPOD1uomAv+gLjwsLDQ==} + engines: {node: '>=16.13'} + hasBin: true + dependencies: + '@cspotcode/source-map-support': 0.8.1 + acorn: 8.10.0 + acorn-walk: 8.3.2 + capnp-ts: 0.7.0 + exit-hook: 2.2.1 + glob-to-regexp: 0.4.1 + stoppable: 1.1.0 + undici: 5.28.4 + workerd: 1.20240512.0 + ws: 8.16.0 + youch: 3.3.3 + zod: 3.22.3 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + /minimal-polyfills@2.2.2: resolution: {integrity: sha512-eEOUq/LH/DbLWihrxUP050Wi7H/N/I2dQT98Ep6SqOpmIbk4sXOI4wqalve66QoZa+6oljbZWU6I6T4dehQGmw==} dev: false @@ -31265,6 +31351,15 @@ packages: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + /resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + dependencies: + is-core-module: 2.13.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + /resolve@2.0.0-next.4: resolution: {integrity: sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==} hasBin: true @@ -34034,6 +34129,7 @@ packages: dependencies: tslib: 1.14.1 typescript: 4.9.5 + dev: true /tsutils@3.21.0(typescript@5.0.4): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} @@ -34053,7 +34149,6 @@ packages: dependencies: tslib: 1.14.1 typescript: 5.1.6 - dev: false /tsutils@3.21.0(typescript@5.2.2): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} @@ -34477,6 +34572,13 @@ packages: dependencies: '@fastify/busboy': 2.0.0 + /undici@5.28.4: + resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} + engines: {node: '>=14.0'} + dependencies: + '@fastify/busboy': 2.0.0 + dev: true + /unfetch@4.2.0: resolution: {integrity: sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==} dev: false @@ -35823,35 +35925,21 @@ packages: '@cloudflare/workerd-windows-64': 1.20231030.0 dev: true - /workerpool@6.2.1: - resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==} + /workerd@1.20240512.0: + resolution: {integrity: sha512-VUBmR1PscAPHEE0OF/G2K7/H1gnr9aDWWZzdkIgWfNKkv8dKFCT75H+GJtUHjfwqz3rYCzaNZmatSXOpLGpF8A==} + engines: {node: '>=16'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@cloudflare/workerd-darwin-64': 1.20240512.0 + '@cloudflare/workerd-darwin-arm64': 1.20240512.0 + '@cloudflare/workerd-linux-64': 1.20240512.0 + '@cloudflare/workerd-linux-arm64': 1.20240512.0 + '@cloudflare/workerd-windows-64': 1.20240512.0 dev: true - /wrangler@3.17.1: - resolution: {integrity: sha512-Pr9+/tjFkthzG63uoVm1NtVvgokT6p92fy1UsOgrntHyTu0pZMC1VJzG0NC8Vhs+z/+yTT8AqVV6AiJb3w8ZOQ==} - engines: {node: '>=16.17.0'} - hasBin: true - dependencies: - '@cloudflare/kv-asset-handler': 0.2.0 - '@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19) - '@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19) - blake3-wasm: 2.1.5 - chokidar: 3.5.3 - esbuild: 0.17.19 - miniflare: 3.20231030.1 - nanoid: 3.3.6 - path-to-regexp: 6.2.1 - resolve.exports: 2.0.2 - selfsigned: 2.4.1 - source-map: 0.6.1 - source-map-support: 0.5.21 - xxhash-wasm: 1.0.2 - optionalDependencies: - fsevents: 2.3.3 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate + /workerpool@6.2.1: + resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==} dev: true /wrangler@3.18.0: @@ -35908,6 +35996,39 @@ packages: - utf-8-validate dev: true + /wrangler@3.57.1(@cloudflare/workers-types@4.20240512.0): + resolution: {integrity: sha512-M8YnWUwdrb8AFiRePtVnzlDn02OX4osWvdl8oVh6eyZqqkqXYg7lwlYBr14Qj92pMN4JvMBmDZoukkYHvwpJRg==} + engines: {node: '>=16.17.0'} + hasBin: true + peerDependencies: + '@cloudflare/workers-types': ^4.20240512.0 + peerDependenciesMeta: + '@cloudflare/workers-types': + optional: true + dependencies: + '@cloudflare/kv-asset-handler': 0.3.2 + '@cloudflare/workers-types': 4.20240512.0 + '@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19) + '@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19) + blake3-wasm: 2.1.5 + chokidar: 3.5.3 + esbuild: 0.17.19 + miniflare: 3.20240512.0 + nanoid: 3.3.7 + path-to-regexp: 6.2.1 + resolve: 1.22.8 + resolve.exports: 2.0.2 + selfsigned: 2.4.1 + source-map: 0.6.1 + xxhash-wasm: 1.0.2 + optionalDependencies: + fsevents: 2.3.3 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + /wrap-ansi@6.2.0: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} From 782d4f75aeedc4d1afc20a896776f222bf5fd250 Mon Sep 17 00:00:00 2001 From: Parker Date: Tue, 28 May 2024 12:10:24 +0100 Subject: [PATCH 3/3] Added tip for setting up github actions using npm run to simplify version pinning (#1132) * added arg to install puppeteer deps to base image * added tip on deploy setup * removed docker changes --- docs/v3/github-actions.mdx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/v3/github-actions.mdx b/docs/v3/github-actions.mdx index 9ba5eeaed..30a553c24 100644 --- a/docs/v3/github-actions.mdx +++ b/docs/v3/github-actions.mdx @@ -95,15 +95,24 @@ To set it in GitHub go to your repository, click on "Settings", "Secrets and var ## Version pinning The CLI and `@trigger.dev/*` package versions need to be in sync, otherwise there will be errors and unpredictable behavior. Hence, the `deploy` command will automatically fail during CI on any version mismatches. +Tip: add the deploy command to your `package.json` file to keep versions managed in the same place. For example: -To ensure a smooth CI experience you can pin the CLI version in the deploy step, like so: +```json +{ + "scripts": { + "deploy:trigger-prod": "npx trigger.dev@3.0.0-beta.34 deploy", + "deploy:trigger": "npx trigger.dev@3.0.0-beta.34 deploy --env staging" + } +} +``` +Your workflow file will follow the version specified in the `package.json` script, like so: ```yaml .github/workflows/release-trigger.yml - name: 🚀 Deploy Trigger.dev env: TRIGGER_ACCESS_TOKEN: ${{ secrets.TRIGGER_ACCESS_TOKEN }} run: | - npx trigger.dev@3.0.0-beta.16 deploy + npm run deploy:trigger ``` You should use the version you run locally during dev and manual deploy. The current version is displayed in the banner, but you can also check it by appending `--version` to any command.