diff --git a/cloudflare/rerun-github-action/.editorconfig b/cloudflare/rerun-github-action/.editorconfig new file mode 100644 index 0000000..a727df3 --- /dev/null +++ b/cloudflare/rerun-github-action/.editorconfig @@ -0,0 +1,12 @@ +# http://editorconfig.org +root = true + +[*] +indent_style = tab +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.yml] +indent_style = space diff --git a/cloudflare/rerun-github-action/.gitignore b/cloudflare/rerun-github-action/.gitignore new file mode 100644 index 0000000..6379b41 --- /dev/null +++ b/cloudflare/rerun-github-action/.gitignore @@ -0,0 +1,9 @@ +.DS_Store +/node_modules +*-lock.* +*.lock +*.log + +/dist + +.wrangler/ diff --git a/cloudflare/rerun-github-action/.prettierrc b/cloudflare/rerun-github-action/.prettierrc new file mode 100644 index 0000000..557d4d5 --- /dev/null +++ b/cloudflare/rerun-github-action/.prettierrc @@ -0,0 +1,19 @@ +{ + "semi": true, + "printWidth": 100, + "singleQuote": true, + "bracketSpacing": true, + "insertPragma": false, + "requirePragma": false, + "jsxSingleQuote": false, + "bracketSameLine": false, + "embeddedLanguageFormatting": "auto", + "htmlWhitespaceSensitivity": "css", + "vueIndentScriptAndStyle": true, + "quoteProps": "consistent", + "proseWrap": "preserve", + "trailingComma": "es5", + "arrowParens": "avoid", + "useTabs": true, + "tabWidth": 2 +} diff --git a/cloudflare/rerun-github-action/README.md b/cloudflare/rerun-github-action/README.md new file mode 100644 index 0000000..70530e7 --- /dev/null +++ b/cloudflare/rerun-github-action/README.md @@ -0,0 +1,5 @@ +# Template: worker-typescript + +[![Deploy with Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/cloudflare/workers-sdk/tree/main/templates/worker-typescript) + +The cloudflare worker to re-trigger GitHub action diff --git a/cloudflare/rerun-github-action/package.json b/cloudflare/rerun-github-action/package.json new file mode 100644 index 0000000..f1bb1c8 --- /dev/null +++ b/cloudflare/rerun-github-action/package.json @@ -0,0 +1,16 @@ +{ + "name": "template-worker-typescript", + "version": "0.0.0", + "private": true, + "scripts": { + "deploy": "wrangler deploy src/index.ts", + "dev": "wrangler dev", + "start": "wrangler dev", + "test": "vitest run" + }, + "devDependencies": { + "@cloudflare/workers-types": "^4.20231016.0", + "typescript": "^5.0.4", + "wrangler": "^3.0.0" + } +} diff --git a/cloudflare/rerun-github-action/src/index.ts b/cloudflare/rerun-github-action/src/index.ts new file mode 100644 index 0000000..a5af57b --- /dev/null +++ b/cloudflare/rerun-github-action/src/index.ts @@ -0,0 +1,89 @@ +/** + * Welcome to Cloudflare Workers! This is your first worker. + * + * - Run `npm run dev` in your terminal to start a development server + * - Open a browser tab at http://localhost:8787/ to see your worker in action + * - Run `npm run deploy` to publish your worker + * + * Learn more at https://developers.cloudflare.com/workers/ + */ + +export interface Env { + // Example binding to KV. Learn more at https://developers.cloudflare.com/workers/runtime-apis/kv/ + // MY_KV_NAMESPACE: KVNamespace; + // + // Example binding to Durable Object. Learn more at https://developers.cloudflare.com/workers/runtime-apis/durable-objects/ + // MY_DURABLE_OBJECT: DurableObjectNamespace; + // + // Example binding to R2. Learn more at https://developers.cloudflare.com/workers/runtime-apis/r2/ + // MY_BUCKET: R2Bucket; + // + // Example binding to a Service. Learn more at https://developers.cloudflare.com/workers/runtime-apis/service-bindings/ + // MY_SERVICE: Fetcher; + // + // Example binding to a Queue. Learn more at https://developers.cloudflare.com/queues/javascript-apis/ + // MY_QUEUE: Queue; +} + +// Structure is defined in https://www.bytebase.com/docs/change-database/webhook/#custom +interface WebhookBody { + level: string; + activity_type: string; + title: string; + description: string; + link: string; + creator_id: number; + creator_name: string; + creator_email: string; + created_ts: number; + issue: { + id: number; + name: string; + status: string; + type: string; + description: string; + }; + project: { + id: number; + name: string; + }; +} + +interface WebhookResponse { + code: number; + message: string; +} + +function jsonResponse(data: WebhookResponse): Response { + return new Response(JSON.stringify(data), { + status: 200, + headers: { + 'Content-Type': 'application/json', + }, + }); +} + +export default { + async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise { + if (request.method === 'POST') { + // Attempt to parse the POST request body as JSON + try { + const body: WebhookBody = await request.json(); + console.debug(body); + + const summary = `Received webhook for issue ${body.issue.name} with status ${body.issue.status}`; + return new Response(JSON.stringify({ code: 0, message: summary }), { + status: 200, + headers: { + 'Content-Type': 'application/json', + }, + }); + } catch (error) { + return jsonResponse({ code: 400, message: 'Invalid JSON' }); + } + } else { + // Handle other HTTP methods or return a method not allowed error + return jsonResponse({ code: 405, message: 'Method Not Allowed' }); + } + }, +}; diff --git a/cloudflare/rerun-github-action/tsconfig.json b/cloudflare/rerun-github-action/tsconfig.json new file mode 100644 index 0000000..9d63c0d --- /dev/null +++ b/cloudflare/rerun-github-action/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "noEmit": true, + "module": "esnext", + "target": "esnext", + "lib": ["esnext"], + "strict": true, + "moduleResolution": "node", + "types": ["@cloudflare/workers-types"] + }, + "exclude": ["node_modules", "dist", "test"] +} diff --git a/cloudflare/rerun-github-action/wrangler.toml b/cloudflare/rerun-github-action/wrangler.toml new file mode 100644 index 0000000..6827074 --- /dev/null +++ b/cloudflare/rerun-github-action/wrangler.toml @@ -0,0 +1,51 @@ +name = "" # todo +main = "./src/index.ts" +compatibility_date = "2022-10-10" + +# Variable bindings. These are arbitrary, plaintext strings (similar to environment variables) +# Note: Use secrets to store sensitive data. +# Docs: https://developers.cloudflare.com/workers/platform/environment-variables +# [vars] +# MY_VARIABLE = "production_value" + +# Bind a KV Namespace. Use KV as persistent storage for small key-value pairs. +# Docs: https://developers.cloudflare.com/workers/runtime-apis/kv +# [[kv_namespaces]] +# binding = "MY_KV_NAMESPACE" +# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + +# Bind an R2 Bucket. Use R2 to store arbitrarily large blobs of data, such as files. +# Docs: https://developers.cloudflare.com/r2/api/workers/workers-api-usage/ +# [[r2_buckets]] +# binding = "MY_BUCKET" +# bucket_name = "my-bucket" + +# Bind a Queue producer. Use this binding to schedule an arbitrary task that may be processed later by a Queue consumer. +# Docs: https://developers.cloudflare.com/queues/get-started +# [[queues.producers]] +# binding = "MY_QUEUE" +# queue = "my-queue" + +# Bind a Queue consumer. Queue Consumers can retrieve tasks scheduled by Producers to act on them. +# Docs: https://developers.cloudflare.com/queues/get-started +# [[queues.consumers]] +# queue = "my-queue" + +# Bind another Worker service. Use this binding to call another Worker without network overhead. +# Docs: https://developers.cloudflare.com/workers/platform/services +# [[services]] +# binding = "MY_SERVICE" +# service = "my-service" + +# Bind a Durable Object. Durable objects are a scale-to-zero compute primitive based on the actor model. +# Durable Objects can live for as long as needed. Use these when you need a long-running "server", such as in realtime apps. +# Docs: https://developers.cloudflare.com/workers/runtime-apis/durable-objects +# [[durable_objects.bindings]] +# name = "MY_DURABLE_OBJECT" +# class_name = "MyDurableObject" + +# Durable Object migrations. +# Docs: https://developers.cloudflare.com/workers/learning/using-durable-objects#configure-durable-object-classes-with-migrations +# [[migrations]] +# tag = "v1" +# new_classes = ["MyDurableObject"]