11import type { VercelRequest , VercelResponse } from '@vercel/node'
2+ import { Redis } from '@upstash/redis'
23import crypto from 'crypto'
34
45const HYGRAPH_SECRET = process . env . HYGRAPH_SECRET !
56const GITHUB_WORKFLOW_URL = process . env . GITHUB_WORKFLOW_URL !
67const GITHUB_TOKEN = process . env . GITHUB_TOKEN !
78
8- // Global timer to accumulate webhook requests
9- let timer : NodeJS . Timeout | null = null
10- const TIMEOUT = 30000
9+ const COOLDOWN_PERIOD = 30000 // seconds
10+ const DEPLOY_KEY = 'last_deploy_timestamp'
11+
12+ const redis = Redis . fromEnv ( ) ;
1113
1214export default async function handler ( req : VercelRequest , res : VercelResponse ) {
1315 if ( req . method !== 'POST' ) {
@@ -34,38 +36,39 @@ export default async function handler(req: VercelRequest, res: VercelResponse) {
3436 return res . status ( 403 ) . json ( { message : 'Invalid signature' } )
3537 }
3638
37- if ( timer ) {
38- return res . status ( 200 ) . json ( { message : 'Deployment already scheduled' } )
39- }
39+ try {
40+ const lastDeployTime = ( await redis . get < number > ( DEPLOY_KEY ) ) || 0
41+ const now = Date . now ( )
42+ const timeSinceLastDeploy = now - lastDeployTime
4043
41- await new Promise < void > ( ( resolve , reject ) => {
42- timer = setTimeout ( async ( ) => {
43- try {
44- const response = await fetch ( GITHUB_WORKFLOW_URL , {
45- method : 'POST' ,
46- headers : {
47- Authorization : `Bearer ${ GITHUB_TOKEN } ` ,
48- Accept : 'application/vnd.github+json' ,
49- 'X-GitHub-Api-Version' : '2022-11-28' ,
50- } ,
51- body : JSON . stringify ( { ref : 'main' } ) ,
52- } )
44+ if ( timeSinceLastDeploy < COOLDOWN_PERIOD ) {
45+ return res . status ( 429 ) . json ( {
46+ message : `Deployment already scheduled. Please wait ${ Math . round ( ( COOLDOWN_PERIOD - timeSinceLastDeploy ) / 1000 ) } seconds.` ,
47+ } )
48+ }
5349
54- if ( ! response . ok ) {
55- console . error ( `Failed to trigger workflow: ${ response . statusText } ` )
56- } else {
57- console . log ( 'Deployment triggered' )
58- }
59- resolve ( )
60- } catch ( error ) {
61- console . error ( 'Error triggering deployment:' , error )
62- reject ( error )
63- } finally {
64- // Reset the timer so that future requests can schedule a new dispatch.
65- timer = null
66- }
67- } , TIMEOUT )
68- } )
50+ await redis . set ( DEPLOY_KEY , now )
6951
70- return res . status ( 200 ) . json ( { message : 'Deployment scheduled' } )
52+ const response = await fetch ( GITHUB_WORKFLOW_URL , {
53+ method : 'POST' ,
54+ headers : {
55+ Authorization : `Bearer ${ GITHUB_TOKEN } ` ,
56+ Accept : 'application/vnd.github+json' ,
57+ 'X-GitHub-Api-Version' : '2022-11-28' ,
58+ } ,
59+ body : JSON . stringify ( { ref : 'main' } ) ,
60+ } )
61+
62+ if ( ! response . ok ) {
63+ throw new Error (
64+ `Failed to trigger workflow: ${ response . statusText } ${ await response . text ( ) } ` ,
65+ )
66+ }
67+
68+ console . log ( 'Deployment triggered' )
69+ return res . status ( 200 ) . json ( { message : 'Deployment triggered' } )
70+ } catch ( error ) {
71+ console . error ( 'Error:' , error )
72+ return res . status ( 500 ) . json ( { message : 'Internal server error' } )
73+ }
7174}
0 commit comments