first pass
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,5 @@
|
|||||||
|
/config.ts
|
||||||
|
|
||||||
# ---> Node
|
# ---> Node
|
||||||
# Logs
|
# Logs
|
||||||
logs
|
logs
|
||||||
|
|||||||
19
Makefile.template
Normal file
19
Makefile.template
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
SHELL := /bin/bash
|
||||||
|
|
||||||
|
id:
|
||||||
|
echo $deploymentId
|
||||||
|
|
||||||
|
status:
|
||||||
|
systemctl status deployer-$host
|
||||||
|
|
||||||
|
log:
|
||||||
|
journalctl -u deployer-$host
|
||||||
|
|
||||||
|
cleanlogs:
|
||||||
|
rm -rf $serviceDir/logs/*
|
||||||
|
|
||||||
|
buildlog:
|
||||||
|
less +F build.log
|
||||||
|
|
||||||
|
stop:
|
||||||
|
systemctl stop deployer-$host
|
||||||
15
package.json
Normal file
15
package.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "deployer2",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "NODE_ENV=development PORT=6001 bun run --hot src/index.ts",
|
||||||
|
"start": "NODE_ENV=production bun run src/index.ts"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@types/object-hash": "^3.0.6",
|
||||||
|
"elysia": "1.4.16",
|
||||||
|
"object-hash": "^3.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/bun": "latest"
|
||||||
|
}
|
||||||
|
}
|
||||||
218
pnpm-lock.yaml
generated
Normal file
218
pnpm-lock.yaml
generated
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
lockfileVersion: '9.0'
|
||||||
|
|
||||||
|
settings:
|
||||||
|
autoInstallPeers: true
|
||||||
|
excludeLinksFromLockfile: false
|
||||||
|
|
||||||
|
importers:
|
||||||
|
|
||||||
|
.:
|
||||||
|
dependencies:
|
||||||
|
'@types/object-hash':
|
||||||
|
specifier: ^3.0.6
|
||||||
|
version: 3.0.6
|
||||||
|
elysia:
|
||||||
|
specifier: 1.4.16
|
||||||
|
version: 1.4.16(@sinclair/typebox@0.34.41)(@types/bun@1.3.3)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)
|
||||||
|
object-hash:
|
||||||
|
specifier: ^3.0.0
|
||||||
|
version: 3.0.0
|
||||||
|
devDependencies:
|
||||||
|
'@octokit/webhooks-types':
|
||||||
|
specifier: ^7.6.1
|
||||||
|
version: 7.6.1
|
||||||
|
'@types/bun':
|
||||||
|
specifier: latest
|
||||||
|
version: 1.3.3
|
||||||
|
|
||||||
|
packages:
|
||||||
|
|
||||||
|
'@borewit/text-codec@0.1.1':
|
||||||
|
resolution: {integrity: sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA==}
|
||||||
|
|
||||||
|
'@octokit/webhooks-types@7.6.1':
|
||||||
|
resolution: {integrity: sha512-S8u2cJzklBC0FgTwWVLaM8tMrDuDMVE4xiTK4EYXM9GntyvrdbSoxqDQa+Fh57CCNApyIpyeqPhhFEmHPfrXgw==}
|
||||||
|
|
||||||
|
'@sinclair/typebox@0.34.41':
|
||||||
|
resolution: {integrity: sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==}
|
||||||
|
|
||||||
|
'@tokenizer/inflate@0.4.1':
|
||||||
|
resolution: {integrity: sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==}
|
||||||
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
'@tokenizer/token@0.3.0':
|
||||||
|
resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==}
|
||||||
|
|
||||||
|
'@types/bun@1.3.3':
|
||||||
|
resolution: {integrity: sha512-ogrKbJ2X5N0kWLLFKeytG0eHDleBYtngtlbu9cyBKFtNL3cnpDZkNdQj8flVf6WTZUX5ulI9AY1oa7ljhSrp+g==}
|
||||||
|
|
||||||
|
'@types/node@24.10.1':
|
||||||
|
resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==}
|
||||||
|
|
||||||
|
'@types/object-hash@3.0.6':
|
||||||
|
resolution: {integrity: sha512-fOBV8C1FIu2ELinoILQ+ApxcUKz4ngq+IWUYrxSGjXzzjUALijilampwkMgEtJ+h2njAW3pi853QpzNVCHB73w==}
|
||||||
|
|
||||||
|
bun-types@1.3.3:
|
||||||
|
resolution: {integrity: sha512-z3Xwlg7j2l9JY27x5Qn3Wlyos8YAp0kKRlrePAOjgjMGS5IG6E7Jnlx736vH9UVI4wUICwwhC9anYL++XeOgTQ==}
|
||||||
|
|
||||||
|
cookie@1.1.1:
|
||||||
|
resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==}
|
||||||
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
debug@4.4.3:
|
||||||
|
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
|
||||||
|
engines: {node: '>=6.0'}
|
||||||
|
peerDependencies:
|
||||||
|
supports-color: '*'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
supports-color:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
elysia@1.4.16:
|
||||||
|
resolution: {integrity: sha512-KZtKN160/bdWVKg2hEgyoNXY8jRRquc+m6PboyisaLZL891I+Ufb7Ja6lDAD7vMQur8sLEWIcidZOzj5lWw9UA==}
|
||||||
|
peerDependencies:
|
||||||
|
'@sinclair/typebox': '>= 0.34.0 < 1'
|
||||||
|
'@types/bun': '>= 1.2.0'
|
||||||
|
exact-mirror: '>= 0.0.9'
|
||||||
|
file-type: '>= 20.0.0'
|
||||||
|
openapi-types: '>= 12.0.0'
|
||||||
|
typescript: '>= 5.0.0'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/bun':
|
||||||
|
optional: true
|
||||||
|
typescript:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
exact-mirror@0.2.5:
|
||||||
|
resolution: {integrity: sha512-u8Wu2lO8nio5lKSJubOydsdNtQmH8ENba5m0nbQYmTvsjksXKYIS1nSShdDlO8Uem+kbo+N6eD5I03cpZ+QsRQ==}
|
||||||
|
peerDependencies:
|
||||||
|
'@sinclair/typebox': ^0.34.15
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@sinclair/typebox':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
fast-decode-uri-component@1.0.1:
|
||||||
|
resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==}
|
||||||
|
|
||||||
|
file-type@21.1.1:
|
||||||
|
resolution: {integrity: sha512-ifJXo8zUqbQ/bLbl9sFoqHNTNWbnPY1COImFfM6CCy7z+E+jC1eY9YfOKkx0fckIg+VljAy2/87T61fp0+eEkg==}
|
||||||
|
engines: {node: '>=20'}
|
||||||
|
|
||||||
|
ieee754@1.2.1:
|
||||||
|
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
|
||||||
|
|
||||||
|
memoirist@0.4.0:
|
||||||
|
resolution: {integrity: sha512-zxTgA0mSYELa66DimuNQDvyLq36AwDlTuVRbnQtB+VuTcKWm5Qc4z3WkSpgsFWHNhexqkIooqpv4hdcqrX5Nmg==}
|
||||||
|
|
||||||
|
ms@2.1.3:
|
||||||
|
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||||
|
|
||||||
|
object-hash@3.0.0:
|
||||||
|
resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
|
||||||
|
engines: {node: '>= 6'}
|
||||||
|
|
||||||
|
openapi-types@12.1.3:
|
||||||
|
resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==}
|
||||||
|
|
||||||
|
strtok3@10.3.4:
|
||||||
|
resolution: {integrity: sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==}
|
||||||
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
token-types@6.1.1:
|
||||||
|
resolution: {integrity: sha512-kh9LVIWH5CnL63Ipf0jhlBIy0UsrMj/NJDfpsy1SqOXlLKEVyXXYrnFxFT1yOOYVGBSApeVnjPw/sBz5BfEjAQ==}
|
||||||
|
engines: {node: '>=14.16'}
|
||||||
|
|
||||||
|
uint8array-extras@1.5.0:
|
||||||
|
resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==}
|
||||||
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
undici-types@7.16.0:
|
||||||
|
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
|
||||||
|
|
||||||
|
snapshots:
|
||||||
|
|
||||||
|
'@borewit/text-codec@0.1.1': {}
|
||||||
|
|
||||||
|
'@octokit/webhooks-types@7.6.1': {}
|
||||||
|
|
||||||
|
'@sinclair/typebox@0.34.41': {}
|
||||||
|
|
||||||
|
'@tokenizer/inflate@0.4.1':
|
||||||
|
dependencies:
|
||||||
|
debug: 4.4.3
|
||||||
|
token-types: 6.1.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@tokenizer/token@0.3.0': {}
|
||||||
|
|
||||||
|
'@types/bun@1.3.3':
|
||||||
|
dependencies:
|
||||||
|
bun-types: 1.3.3
|
||||||
|
|
||||||
|
'@types/node@24.10.1':
|
||||||
|
dependencies:
|
||||||
|
undici-types: 7.16.0
|
||||||
|
|
||||||
|
'@types/object-hash@3.0.6': {}
|
||||||
|
|
||||||
|
bun-types@1.3.3:
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 24.10.1
|
||||||
|
|
||||||
|
cookie@1.1.1: {}
|
||||||
|
|
||||||
|
debug@4.4.3:
|
||||||
|
dependencies:
|
||||||
|
ms: 2.1.3
|
||||||
|
|
||||||
|
elysia@1.4.16(@sinclair/typebox@0.34.41)(@types/bun@1.3.3)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3):
|
||||||
|
dependencies:
|
||||||
|
'@sinclair/typebox': 0.34.41
|
||||||
|
cookie: 1.1.1
|
||||||
|
exact-mirror: 0.2.5(@sinclair/typebox@0.34.41)
|
||||||
|
fast-decode-uri-component: 1.0.1
|
||||||
|
file-type: 21.1.1
|
||||||
|
memoirist: 0.4.0
|
||||||
|
openapi-types: 12.1.3
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/bun': 1.3.3
|
||||||
|
|
||||||
|
exact-mirror@0.2.5(@sinclair/typebox@0.34.41):
|
||||||
|
optionalDependencies:
|
||||||
|
'@sinclair/typebox': 0.34.41
|
||||||
|
|
||||||
|
fast-decode-uri-component@1.0.1: {}
|
||||||
|
|
||||||
|
file-type@21.1.1:
|
||||||
|
dependencies:
|
||||||
|
'@tokenizer/inflate': 0.4.1
|
||||||
|
strtok3: 10.3.4
|
||||||
|
token-types: 6.1.1
|
||||||
|
uint8array-extras: 1.5.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
ieee754@1.2.1: {}
|
||||||
|
|
||||||
|
memoirist@0.4.0: {}
|
||||||
|
|
||||||
|
ms@2.1.3: {}
|
||||||
|
|
||||||
|
object-hash@3.0.0: {}
|
||||||
|
|
||||||
|
openapi-types@12.1.3: {}
|
||||||
|
|
||||||
|
strtok3@10.3.4:
|
||||||
|
dependencies:
|
||||||
|
'@tokenizer/token': 0.3.0
|
||||||
|
|
||||||
|
token-types@6.1.1:
|
||||||
|
dependencies:
|
||||||
|
'@borewit/text-codec': 0.1.1
|
||||||
|
'@tokenizer/token': 0.3.0
|
||||||
|
ieee754: 1.2.1
|
||||||
|
|
||||||
|
uint8array-extras@1.5.0: {}
|
||||||
|
|
||||||
|
undici-types@7.16.0: {}
|
||||||
16
service.template
Normal file
16
service.template
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Deployment of $host (on port $port, from $repo/$branch:$commitHash) [$deploymentId]
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
Environment="PORT=$port"
|
||||||
|
ExecStart=make start
|
||||||
|
User=drm
|
||||||
|
WorkingDirectory=$serviceDir/src
|
||||||
|
Restart=no
|
||||||
|
StandardOutput=file:$logsDir/start.log
|
||||||
|
StandardError=file:$logsDir/start.log
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
29
src/config.ts
Normal file
29
src/config.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import userConfig from "../config";
|
||||||
|
import hash from "object-hash";
|
||||||
|
|
||||||
|
export type DeployerConfig = {
|
||||||
|
services: {
|
||||||
|
[host: string]: {
|
||||||
|
user: string;
|
||||||
|
repo: string;
|
||||||
|
branch: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
giteaUrl: string;
|
||||||
|
directory: string;
|
||||||
|
basePort: number;
|
||||||
|
token: string;
|
||||||
|
systemServicesDir: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const config = userConfig as DeployerConfig;
|
||||||
|
export const indexedConfig = Object.fromEntries(
|
||||||
|
Object.entries(config.services).map(([host, service], i) => [
|
||||||
|
hash(service),
|
||||||
|
{
|
||||||
|
...service,
|
||||||
|
host,
|
||||||
|
port: config.basePort + i,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
);
|
||||||
68
src/deploy.ts
Normal file
68
src/deploy.ts
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
import { $ } from "bun";
|
||||||
|
import path from "path";
|
||||||
|
import { config } from "./config";
|
||||||
|
|
||||||
|
type DeployInstance = {
|
||||||
|
host: string;
|
||||||
|
user: string;
|
||||||
|
repo: string;
|
||||||
|
branch: string;
|
||||||
|
commitHash: string;
|
||||||
|
port: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deploy = async ({
|
||||||
|
host,
|
||||||
|
user,
|
||||||
|
repo,
|
||||||
|
branch,
|
||||||
|
port,
|
||||||
|
commitHash,
|
||||||
|
}: DeployInstance) => {
|
||||||
|
const deploymentId = new Date().toISOString();
|
||||||
|
|
||||||
|
const serviceDir = path.join(config.directory, host);
|
||||||
|
|
||||||
|
// Fetch
|
||||||
|
await $`
|
||||||
|
cd ${serviceDir}
|
||||||
|
mkdir -p src
|
||||||
|
mkdir -p logs
|
||||||
|
git clone \
|
||||||
|
-b ${branch} \
|
||||||
|
http://deployer:${config.token}@${config.giteaUrl}/${user}/${repo} \
|
||||||
|
${serviceDir}/src
|
||||||
|
cd src
|
||||||
|
git fetch origin ${branch}
|
||||||
|
git reset --hard origin/${branch}
|
||||||
|
git checkout ${commitHash}
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Build
|
||||||
|
await $`
|
||||||
|
cd ${serviceDir}/src
|
||||||
|
make build
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Register service
|
||||||
|
const systemdServiceName = `deployer-${host}.service`;
|
||||||
|
await $`
|
||||||
|
cat template.service | envsubst > ${serviceDir}/${systemdServiceName}
|
||||||
|
ln -sf ${serviceDir}/${systemdServiceName} ${config.systemServicesDir}/${systemdServiceName}
|
||||||
|
`.env({
|
||||||
|
host,
|
||||||
|
port: port.toString(),
|
||||||
|
repo,
|
||||||
|
branch,
|
||||||
|
commitHash,
|
||||||
|
deploymentId,
|
||||||
|
logsDir: path.join(serviceDir, "logs"),
|
||||||
|
serviceDir,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Start!
|
||||||
|
await $`
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl restart ${systemdServiceName}
|
||||||
|
`;
|
||||||
|
};
|
||||||
216
src/giteaTypes.ts
Normal file
216
src/giteaTypes.ts
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
export interface PushEvent {
|
||||||
|
ref: string;
|
||||||
|
before: string;
|
||||||
|
after: string;
|
||||||
|
compare_url: string;
|
||||||
|
commits: Commit[];
|
||||||
|
total_commits: number;
|
||||||
|
head_commit: HeadCommit;
|
||||||
|
repository: Repository;
|
||||||
|
pusher: Pusher;
|
||||||
|
sender: Sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Commit {
|
||||||
|
id: string;
|
||||||
|
message: string;
|
||||||
|
url: string;
|
||||||
|
author: Author;
|
||||||
|
committer: Committer;
|
||||||
|
verification: any;
|
||||||
|
timestamp: string;
|
||||||
|
added: any;
|
||||||
|
removed: any;
|
||||||
|
modified: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Author {
|
||||||
|
name: string;
|
||||||
|
email: string;
|
||||||
|
username: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Committer {
|
||||||
|
name: string;
|
||||||
|
email: string;
|
||||||
|
username: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HeadCommit {
|
||||||
|
id: string;
|
||||||
|
message: string;
|
||||||
|
url: string;
|
||||||
|
author: Author2;
|
||||||
|
committer: Committer2;
|
||||||
|
verification: any;
|
||||||
|
timestamp: string;
|
||||||
|
added: any;
|
||||||
|
removed: any;
|
||||||
|
modified: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Author2 {
|
||||||
|
name: string;
|
||||||
|
email: string;
|
||||||
|
username: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Committer2 {
|
||||||
|
name: string;
|
||||||
|
email: string;
|
||||||
|
username: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Repository {
|
||||||
|
id: number;
|
||||||
|
owner: Owner;
|
||||||
|
name: string;
|
||||||
|
full_name: string;
|
||||||
|
description: string;
|
||||||
|
empty: boolean;
|
||||||
|
private: boolean;
|
||||||
|
fork: boolean;
|
||||||
|
template: boolean;
|
||||||
|
mirror: boolean;
|
||||||
|
size: number;
|
||||||
|
language: string;
|
||||||
|
languages_url: string;
|
||||||
|
html_url: string;
|
||||||
|
url: string;
|
||||||
|
link: string;
|
||||||
|
ssh_url: string;
|
||||||
|
clone_url: string;
|
||||||
|
original_url: string;
|
||||||
|
website: string;
|
||||||
|
stars_count: number;
|
||||||
|
forks_count: number;
|
||||||
|
watchers_count: number;
|
||||||
|
open_issues_count: number;
|
||||||
|
open_pr_counter: number;
|
||||||
|
release_counter: number;
|
||||||
|
default_branch: string;
|
||||||
|
archived: boolean;
|
||||||
|
created_at: string;
|
||||||
|
updated_at: string;
|
||||||
|
archived_at: string;
|
||||||
|
permissions: Permissions;
|
||||||
|
has_code: boolean;
|
||||||
|
has_issues: boolean;
|
||||||
|
internal_tracker: InternalTracker;
|
||||||
|
has_wiki: boolean;
|
||||||
|
has_pull_requests: boolean;
|
||||||
|
has_projects: boolean;
|
||||||
|
projects_mode: string;
|
||||||
|
has_releases: boolean;
|
||||||
|
has_packages: boolean;
|
||||||
|
has_actions: boolean;
|
||||||
|
ignore_whitespace_conflicts: boolean;
|
||||||
|
allow_merge_commits: boolean;
|
||||||
|
allow_rebase: boolean;
|
||||||
|
allow_rebase_explicit: boolean;
|
||||||
|
allow_squash_merge: boolean;
|
||||||
|
allow_fast_forward_only_merge: boolean;
|
||||||
|
allow_rebase_update: boolean;
|
||||||
|
allow_manual_merge: boolean;
|
||||||
|
autodetect_manual_merge: boolean;
|
||||||
|
default_delete_branch_after_merge: boolean;
|
||||||
|
default_merge_style: string;
|
||||||
|
default_allow_maintainer_edit: boolean;
|
||||||
|
avatar_url: string;
|
||||||
|
internal: boolean;
|
||||||
|
mirror_interval: string;
|
||||||
|
object_format_name: string;
|
||||||
|
mirror_updated: string;
|
||||||
|
topics: any[];
|
||||||
|
licenses: any[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Owner {
|
||||||
|
id: number;
|
||||||
|
login: string;
|
||||||
|
login_name: string;
|
||||||
|
source_id: number;
|
||||||
|
full_name: string;
|
||||||
|
email: string;
|
||||||
|
avatar_url: string;
|
||||||
|
html_url: string;
|
||||||
|
language: string;
|
||||||
|
is_admin: boolean;
|
||||||
|
last_login: string;
|
||||||
|
created: string;
|
||||||
|
restricted: boolean;
|
||||||
|
active: boolean;
|
||||||
|
prohibit_login: boolean;
|
||||||
|
location: string;
|
||||||
|
website: string;
|
||||||
|
description: string;
|
||||||
|
visibility: string;
|
||||||
|
followers_count: number;
|
||||||
|
following_count: number;
|
||||||
|
starred_repos_count: number;
|
||||||
|
username: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Permissions {
|
||||||
|
admin: boolean;
|
||||||
|
push: boolean;
|
||||||
|
pull: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InternalTracker {
|
||||||
|
enable_time_tracker: boolean;
|
||||||
|
allow_only_contributors_to_track_time: boolean;
|
||||||
|
enable_issue_dependencies: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Pusher {
|
||||||
|
id: number;
|
||||||
|
login: string;
|
||||||
|
login_name: string;
|
||||||
|
source_id: number;
|
||||||
|
full_name: string;
|
||||||
|
email: string;
|
||||||
|
avatar_url: string;
|
||||||
|
html_url: string;
|
||||||
|
language: string;
|
||||||
|
is_admin: boolean;
|
||||||
|
last_login: string;
|
||||||
|
created: string;
|
||||||
|
restricted: boolean;
|
||||||
|
active: boolean;
|
||||||
|
prohibit_login: boolean;
|
||||||
|
location: string;
|
||||||
|
website: string;
|
||||||
|
description: string;
|
||||||
|
visibility: string;
|
||||||
|
followers_count: number;
|
||||||
|
following_count: number;
|
||||||
|
starred_repos_count: number;
|
||||||
|
username: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Sender {
|
||||||
|
id: number;
|
||||||
|
login: string;
|
||||||
|
login_name: string;
|
||||||
|
source_id: number;
|
||||||
|
full_name: string;
|
||||||
|
email: string;
|
||||||
|
avatar_url: string;
|
||||||
|
html_url: string;
|
||||||
|
language: string;
|
||||||
|
is_admin: boolean;
|
||||||
|
last_login: string;
|
||||||
|
created: string;
|
||||||
|
restricted: boolean;
|
||||||
|
active: boolean;
|
||||||
|
prohibit_login: boolean;
|
||||||
|
location: string;
|
||||||
|
website: string;
|
||||||
|
description: string;
|
||||||
|
visibility: string;
|
||||||
|
followers_count: number;
|
||||||
|
following_count: number;
|
||||||
|
starred_repos_count: number;
|
||||||
|
username: string;
|
||||||
|
}
|
||||||
42
src/index.ts
Normal file
42
src/index.ts
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import { Elysia } from "elysia";
|
||||||
|
import hash from "object-hash";
|
||||||
|
import { indexedConfig } from "./config";
|
||||||
|
import { deploy } from "./deploy";
|
||||||
|
import { PushEvent } from "./giteaTypes";
|
||||||
|
|
||||||
|
const port = 6001;
|
||||||
|
|
||||||
|
new Elysia()
|
||||||
|
.onError(({ error }) => console.error(error))
|
||||||
|
.onRequest(({ request }) => {
|
||||||
|
console.log(request.method, new URL(request.url).pathname);
|
||||||
|
})
|
||||||
|
.get("/ping", () => "pong")
|
||||||
|
.post("/gitea", ({ body }) => {
|
||||||
|
const event = body as PushEvent;
|
||||||
|
|
||||||
|
const user = event.repository.owner.username;
|
||||||
|
const repo = event.repository.name;
|
||||||
|
const branch = event.ref.replace(/^(refs\/heads\/)/, "");
|
||||||
|
const commitHash = event.before;
|
||||||
|
|
||||||
|
const service =
|
||||||
|
indexedConfig[
|
||||||
|
hash({
|
||||||
|
user,
|
||||||
|
repo,
|
||||||
|
branch,
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
if (service == null) {
|
||||||
|
console.error(`No service defined for ${user}/${repo}:${branch}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deploy({ ...service, commitHash });
|
||||||
|
return "deploying";
|
||||||
|
})
|
||||||
|
.listen(port);
|
||||||
|
|
||||||
|
console.log(`started deployer2 on :${port}`);
|
||||||
Reference in New Issue
Block a user