✨ Post deploy script
This commit is contained in:
		| @@ -6,7 +6,7 @@ import * as fs from "node:fs" | ||||
| import * as child_process from "node:child_process" | ||||
| import * as path from "node:path" | ||||
| import { createAuthHeader } from "../utils/auth.ts" | ||||
| import { RsLocalConfig } from "../utils/config-local.ts" | ||||
| import { RsLocalConfig, type RsLocalConfigDeploymentPostActionData } from "../utils/config-local.ts" | ||||
| import * as os from "node:os" | ||||
|  | ||||
| export class DeployCommand extends Command { | ||||
| @@ -26,7 +26,7 @@ export class DeployCommand extends Command { | ||||
|   site = Option.String({ required: false }) | ||||
|   input = Option.String({ required: false }) | ||||
|  | ||||
|   async deploy(serverLabel: string, region: string, site: string, input: string) { | ||||
|   async deploy(serverLabel: string, region: string, site: string, input: string, postDeploy: RsLocalConfigDeploymentPostActionData | null = null) { | ||||
|     const cfg = await RsConfig.getInstance() | ||||
|     const server = cfg.config.servers.find(item => item.label === serverLabel) | ||||
|     if (server == null) { | ||||
| @@ -59,6 +59,18 @@ export class DeployCommand extends Command { | ||||
|     try { | ||||
|       const payload = new FormData() | ||||
|       payload.set("attachments", await fs.openAsBlob(input), isDirectory ? "dist.zip" : path.basename(input)) | ||||
|  | ||||
|       if(postDeploy) { | ||||
|         if(postDeploy.command) { | ||||
|           payload.set("post-deploy-script", postDeploy.command) | ||||
|         } else if(postDeploy.scriptPath) { | ||||
|           payload.set("post-deploy-script", fs.readFileSync(postDeploy.scriptPath, "utf8")) | ||||
|         } else { | ||||
|           this.context.stdout.write(chalk.yellow(`Configured post deploy action but no script provided, skip performing post deploy action...\n`)) | ||||
|         } | ||||
|         payload.set("post-deploy-environment", postDeploy.environment?.join("\n") ?? "") | ||||
|       } | ||||
|  | ||||
|       const res = await fetch(`${server.url}/webhooks/publish/${region}/${site}?mimetype=application/zip`, { | ||||
|         method: "PUT", | ||||
|         body: payload, | ||||
|   | ||||
| @@ -15,6 +15,7 @@ interface RsLocalConfigDeploymentData { | ||||
|   path: string | ||||
|   region: string | ||||
|   site: string | ||||
|   postDeploy?: RsLocalConfigDeploymentPostActionData | ||||
|   autoBuild?: RsLocalConfigDeploymentAutoBuildData | ||||
| } | ||||
|  | ||||
| @@ -23,6 +24,12 @@ interface RsLocalConfigDeploymentAutoBuildData { | ||||
|   environment?: string[] | ||||
| } | ||||
|  | ||||
| interface RsLocalConfigDeploymentPostActionData { | ||||
|   command?: string | ||||
|   scriptPath?: string | ||||
|   environment?: string[] | ||||
| } | ||||
|  | ||||
| class RsLocalConfig { | ||||
|   private static instance: RsLocalConfig | ||||
|  | ||||
| @@ -57,4 +64,4 @@ class RsLocalConfig { | ||||
|   } | ||||
| } | ||||
|  | ||||
| export { RsLocalConfig, type RsLocalConfigData } | ||||
| export { RsLocalConfig, type RsLocalConfigData, type RsLocalConfigDeploymentPostActionData } | ||||
| @@ -60,7 +60,7 @@ func (v *Destination) GetType() DestinationType { | ||||
| func (v *Destination) GetRawUri() (string, url.Values) { | ||||
| 	uri := strings.SplitN(v.Uri, "://", 2)[1] | ||||
| 	data := strings.SplitN(uri, "?", 2) | ||||
| 	data = append(data, " ") // Make the data array least have two elements | ||||
| 	data = append(data, " ") // Make the data array at least have two elements | ||||
| 	qs, _ := url.ParseQuery(data[1]) | ||||
|  | ||||
| 	return data[0], qs | ||||
|   | ||||
| @@ -2,9 +2,12 @@ package sideload | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"git.solsynth.dev/goatworks/roadsign/pkg/warden" | ||||
| 	"os" | ||||
| 	"os/exec" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
|  | ||||
| 	"git.solsynth.dev/goatworks/roadsign/pkg/navi" | ||||
| 	"github.com/gofiber/fiber/v2" | ||||
| @@ -50,7 +53,7 @@ func doPublish(c *fiber.Ctx) error { | ||||
| 		return fiber.ErrNotFound | ||||
| 	} | ||||
|  | ||||
| 	if c.Query("overwrite", "yes") == "yes" { | ||||
| 	if c.QueryBool("overwrite", true) { | ||||
| 		files, _ := filepath.Glob(filepath.Join(workdir, "*")) | ||||
| 		for _, file := range files { | ||||
| 			_ = os.Remove(file) | ||||
| @@ -74,6 +77,7 @@ func doPublish(c *fiber.Ctx) error { | ||||
| 						return err | ||||
| 					} | ||||
| 				} | ||||
| 				_ = os.Remove(dst) | ||||
| 			default: | ||||
| 				dst := filepath.Join(workdir, file.Filename) | ||||
| 				if err := c.SaveFile(file, dst); err != nil { | ||||
| @@ -83,6 +87,15 @@ func doPublish(c *fiber.Ctx) error { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if postScript := c.FormValue("post-deploy-script", ""); len(postScript) > 0 { | ||||
| 		cmd := exec.Command("sh", "-c", postScript) | ||||
| 		cmd.Dir = filepath.Join(workdir) | ||||
| 		cmd.Env = append(cmd.Env, strings.Split(c.FormValue("post-deploy-environment", ""), "\n")...) | ||||
| 		if err := cmd.Run(); err != nil { | ||||
| 			return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("post deploy script runs failed: %v", err)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if instance != nil { | ||||
| 		_ = instance.Wake() | ||||
| 	} | ||||
|   | ||||
| @@ -77,7 +77,7 @@ func doSync(c *fiber.Ctx) error { | ||||
| 		_ = instance.Stop() | ||||
| 	} | ||||
| 	for _, instance := range startQueue { | ||||
| 		_ = instance.Start() | ||||
| 		_ = instance.Wake() | ||||
| 	} | ||||
|  | ||||
| 	return c.SendStatus(fiber.StatusOK) | ||||
|   | ||||
| @@ -62,15 +62,9 @@ func (v *AppInstance) Wake() error { | ||||
| 	} | ||||
| 	if v.Cmd.ProcessState.Exited() { | ||||
| 		return v.Start() | ||||
| 	} else if v.Cmd.ProcessState.Exited() { | ||||
| 		return fmt.Errorf("process already dead") | ||||
| 	} | ||||
| 	if v.Cmd.ProcessState.Exited() { | ||||
| 		return fmt.Errorf("cannot start process") | ||||
| 	} else { | ||||
| 	return nil | ||||
| } | ||||
| } | ||||
|  | ||||
| func (v *AppInstance) Start() error { | ||||
| 	manifest := v.Manifest | ||||
| @@ -93,7 +87,7 @@ func (v *AppInstance) Start() error { | ||||
| 			} else if v.Cmd != nil && v.Cmd.ProcessState == nil { | ||||
| 				v.Status = AppStarted | ||||
| 			} else { | ||||
| 				v.Status = lo.Ternary(v.Cmd == nil, AppExited, AppFailure) | ||||
| 				v.Status = AppFailure | ||||
| 				v.Cmd = nil | ||||
| 				return | ||||
| 			} | ||||
| @@ -119,6 +113,7 @@ func (v *AppInstance) Stop() error { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	v.Status = AppExited | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user