Deploy Udpate

This commit is contained in:
Rokojori 2026-07-13 21:42:21 +02:00
parent ddb25f72a0
commit a54d1042cf
3 changed files with 56 additions and 22 deletions

View File

@ -1,22 +0,0 @@
name: Deploy
on:
push:
branches:
- main
jobs:
deploy:
runs-on: self-hosted
steps:
- name: Pull latest
run: git -C /opt/roject pull
- name: Install dependencies
run: npm --prefix /opt/roject ci --omit=dev
- name: Build
run: npm --prefix /opt/roject run build
- name: Restart service
run: systemctl restart roject

View File

@ -9,11 +9,13 @@ import localesRouter from './routes/locales';
import layoutRouter from './routes/layout'; import layoutRouter from './routes/layout';
import rojosRouter from './routes/rojos'; import rojosRouter from './routes/rojos';
import { generateLocales } from './localeGenerator'; import { generateLocales } from './localeGenerator';
import deployRouter from './routes/deploy';
generateLocales(); generateLocales();
const app = express(); const app = express();
app.use( '/api/deploy', deployRouter );
app.use( express.json() ); app.use( express.json() );
app.use( express.text( { type: 'text/plain' } ) ); app.use( express.text( { type: 'text/plain' } ) );
app.use( cookieParser() ); app.use( cookieParser() );

View File

@ -0,0 +1,54 @@
import { Router } from 'express';
import express from 'express';
import { spawn } from 'child_process';
import { createHmac, timingSafeEqual } from 'crypto';
const router = Router();
const DEPLOY_SECRET = process.env.DEPLOY_WEBHOOK_SECRET ?? '';
const APP_DIR = process.env.APP_DIR ?? '/opt/roject';
const SERVICE_NAME = process.env.SERVICE_NAME ?? 'roject';
function verifySignature( rawBody: Buffer, signature: string ): boolean {
if ( !DEPLOY_SECRET ) return false;
const expected = createHmac( 'sha256', DEPLOY_SECRET ).update( rawBody ).digest( 'hex' );
try {
return timingSafeEqual( Buffer.from( signature ), Buffer.from( expected ) );
} catch {
return false;
}
}
function triggerDeploy() {
const cmd = `git -C ${APP_DIR} pull && npm --prefix ${APP_DIR} run build && systemctl restart ${SERVICE_NAME}`;
const child = spawn( 'bash', [ '-c', cmd ], { detached: true, stdio: 'ignore' } );
child.unref();
}
router.post( '/', express.raw( { type: 'application/json' } ), ( req, res ) => {
const signature = req.headers[ 'x-gitea-signature' ] as string;
if ( !DEPLOY_SECRET ) {
console.error( '[deploy] DEPLOY_WEBHOOK_SECRET is not set' );
res.status( 500 ).json( { error: 'Deploy not configured' } );
return;
}
if ( !signature || !verifySignature( req.body as Buffer, signature ) ) {
res.status( 401 ).json( { error: 'Invalid signature' } );
return;
}
const payload = JSON.parse( ( req.body as Buffer ).toString() );
if ( payload.ref !== 'refs/heads/main' ) {
res.json( { message: 'Not main branch, skipping' } );
return;
}
console.log( `[deploy] triggered by push from ${payload.pusher?.login ?? 'unknown'}` );
res.json( { message: 'Deploy triggered' } );
triggerDeploy();
} );
export default router;