Last active
January 6, 2026 20:36
-
-
Save billyvg/eb67f9051ed404c1908b79847e4cf19f to your computer and use it in GitHub Desktop.
Komodo Action: Create a new stack on git push
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Create a new Komodo Action and paste the following in. Take the webhook URL and connect | |
| * it to your git host so that the webhook is called on pushes. | |
| * | |
| * You may need to modify it to your liking but the code detects when files are added and assumes | |
| * the format: `<stackName>/compose.yaml` | |
| */ | |
| // I used to use a template to create a new stack, but | |
| // templates cause my update procedure to fail, so I just define my template here instead | |
| // I created an test action and called `komodo.read('GetStack', {stack});` to my stack template | |
| // to get the following values | |
| const STACK_CONFIG_TEMPLATE: Partial<Types.StackConfig> = { | |
| server_id: <server_id>, | |
| linked_repo: <linked_repo_id>, | |
| auto_pull: true, | |
| poll_for_updates: true, | |
| environment: "TZ=America/New_York", | |
| // ... additional config | |
| }; | |
| // Access arguments using the 'ARGS' object. | |
| const {commits}: {commits: Array<{added: null|string[]}>} = ARGS.WEBHOOK_BODY; | |
| const newStacks: Record<string, {compose: string; env: string[]}> = commits | |
| .filter(commit => Array.isArray(commit?.added)) | |
| .reduce((acc, commit) => { | |
| // Returns dict of {stackName, {compose: string, env: string[]}}, | |
| // which needs to be merged for each commit | |
| commit.added | |
| .forEach(file => { | |
| // needs to be in format of `<stackName>/compose.yaml` | |
| const [stackName, fileName] = file.split('/'); | |
| const stackValue = acc[stackName] ?? {}; | |
| const envFiles = stackValue.env ?? []; | |
| if (fileName.endsWith('compose.yaml') || fileName.endsWith('compose.yml')) { | |
| stackValue.compose = fileName; | |
| } | |
| if (fileName.endsWith('.env')) { | |
| envFiles.push(fileName); | |
| } | |
| acc[stackName] = { | |
| compose: stackValue.compose, | |
| env: envFiles, | |
| }; | |
| }); | |
| return acc; | |
| }, {}) | |
| if (!Object.keys(newStacks).length) { | |
| return; | |
| } | |
| for (const [stackName, stackObject] of Object.entries(newStacks)) { | |
| if (stackObject.compose) { | |
| createStack(stackName, stackObject.env); | |
| } else if (stackObject.env?.length) { | |
| // TODO, !compose && env.length (env file was later added) --> get existing stack and update the additional_env_files | |
| try { | |
| const stack = await komodo.read('GetStack', {stack: stackName}); | |
| console.log({stack}); | |
| await komodo.write('UpdateStack', { | |
| id: stack.id, | |
| config: { | |
| additional_env_files: [ | |
| ...stack.config.additional_env_files, | |
| ...stackObject.env, | |
| ], | |
| } | |
| }); | |
| } catch { | |
| // stack doesn't exist... can't do anything | |
| } | |
| } | |
| } | |
| async function createStack(stackName: string, envFiles: string[] = []) { | |
| /* | |
| const STACK_TEMPLATE_NAME = 'git-template'; | |
| let stackTemplate: Types.GetStackResponse|null; | |
| try { | |
| stackTemplate = await komodo.read('GetStack', {stack: STACK_TEMPLATE_NAME}); | |
| } catch {} | |
| */ | |
| try { | |
| const stack = await komodo.read('GetStack', {stack: stackName}); | |
| // This shouldn't happen because above will throw if stack doesn't exist | |
| if (stack) { | |
| return stack; | |
| } | |
| } catch { | |
| // Create stack | |
| const result = await komodo.write('CreateStack', { | |
| name: stackName, | |
| config: { | |
| //...stackTemplate?.config, | |
| ...STACK_CONFIG_TEMPLATE, | |
| additional_env_files: envFiles, | |
| run_directory: stackName, | |
| } | |
| }); | |
| if (result) { | |
| console.log(`Created new stack: ${result.name}`); | |
| await komodo.execute('DeployStack', {stack: result.name}); | |
| } | |
| return result; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment