diff options
Diffstat (limited to 'worker')
| -rw-r--r-- | worker/scripts/coolify_webhook.ts | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/worker/scripts/coolify_webhook.ts b/worker/scripts/coolify_webhook.ts new file mode 100644 index 0000000..454bc56 --- /dev/null +++ b/worker/scripts/coolify_webhook.ts @@ -0,0 +1,83 @@ +#!/usr/bin/env node + +import { + Either, + getRequiredEnvVars, + LogTraceable, + LogMetricTraceable, + Metric, + TraceUtil, +} from '@emprespresso/pengueno'; +import { Infisical, type SecureNote } from '@emprespresso/ci_worker'; +import { CoolifyWebhookJob } from '@emprespresso/ci_model'; + +const eitherJob = getRequiredEnvVars(['webhookUrl']).mapRight( + (baseArgs) => + <CoolifyWebhookJob>{ + type: 'coolify_webhook.js', + arguments: baseArgs, + }, +); + +const eitherVault = Infisical.getConfigFromEnvironment().mapRight((config) => new Infisical(config)); + +const webhookMetric = Metric.fromName('coolify_webhook.trigger').asResult(); +const _logJob = LogTraceable.of(eitherJob).flatMap(TraceUtil.withTrace('coolify_webhook')); +await LogMetricTraceable.ofLogTraceable(_logJob) + .flatMap(TraceUtil.withMetricTrace(webhookMetric)) + .peek((tEitherJob) => tEitherJob.trace.trace('starting coolify webhook trigger! (⑅˘꒳˘)')) + .map((tEitherJob) => + tEitherJob.get().flatMapAsync((job) => + eitherVault.flatMapAsync(async (vault) => { + const eitherKey = await vault.unlock(tEitherJob); + tEitherJob.trace.trace('unlocked vault :3'); + return eitherKey.mapRight((key) => ({ job, key, vault })); + }), + ), + ) + .map(async (tEitherJobVault) => + (await tEitherJobVault.get()).flatMapAsync(({ job, key, vault }) => + vault + .fetchSecret<SecureNote>(tEitherJobVault, key, 'coolify') + .then((e) => e.mapRight(({ notes }) => ({ job, webhookSecret: notes }))) + .finally(() => vault.lock(tEitherJobVault, key)), + ), + ) + .map(async (tEitherJobAndSecret) => { + const eitherJobAndSecret = await tEitherJobAndSecret.get(); + return eitherJobAndSecret.flatMapAsync(async ({ job, webhookSecret }) => { + tEitherJobAndSecret.trace.trace(`triggering webhook at ${job.arguments.webhookUrl} (◕ᴗ◕✿)`); + + return Either.fromFailableAsync<Error, string>(() => + fetch(job.arguments.webhookUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${webhookSecret}`, + }, + body: JSON.stringify({}), + }).then(async (response) => { + if (!response.ok) { + throw new Error( + `webhook request failed with status ${response.status}: ${await response.text()}`, + ); + } + return response.text(); + }), + ).then((e) => { + e.mapRight((responseText) => + tEitherJobAndSecret.trace.trace(`webhook response: ${responseText}`), + ); + return e; + }); + }); + }) + .peek(TraceUtil.promiseify(TraceUtil.traceResultingEither(webhookMetric))) + .map(async (tEitherJob) => { + const eitherJob = await tEitherJob.get(); + return eitherJob.fold( + (e) => Promise.reject(e), + () => Promise.resolve(0), + ); + }) + .get(); |
