Post deploy script

This commit is contained in:
LittleSheep 2024-10-03 20:59:18 +08:00
parent 11a9a4a929
commit 34f20e02ae
6 changed files with 41 additions and 14 deletions

View File

@ -6,7 +6,7 @@ import * as fs from "node:fs"
import * as child_process from "node:child_process" import * as child_process from "node:child_process"
import * as path from "node:path" import * as path from "node:path"
import { createAuthHeader } from "../utils/auth.ts" 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" import * as os from "node:os"
export class DeployCommand extends Command { export class DeployCommand extends Command {
@ -26,7 +26,7 @@ export class DeployCommand extends Command {
site = Option.String({ required: false }) site = Option.String({ required: false })
input = 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 cfg = await RsConfig.getInstance()
const server = cfg.config.servers.find(item => item.label === serverLabel) const server = cfg.config.servers.find(item => item.label === serverLabel)
if (server == null) { if (server == null) {
@ -59,6 +59,18 @@ export class DeployCommand extends Command {
try { try {
const payload = new FormData() const payload = new FormData()
payload.set("attachments", await fs.openAsBlob(input), isDirectory ? "dist.zip" : path.basename(input)) 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`, { const res = await fetch(`${server.url}/webhooks/publish/${region}/${site}?mimetype=application/zip`, {
method: "PUT", method: "PUT",
body: payload, body: payload,

View File

@ -15,6 +15,7 @@ interface RsLocalConfigDeploymentData {
path: string path: string
region: string region: string
site: string site: string
postDeploy?: RsLocalConfigDeploymentPostActionData
autoBuild?: RsLocalConfigDeploymentAutoBuildData autoBuild?: RsLocalConfigDeploymentAutoBuildData
} }
@ -23,6 +24,12 @@ interface RsLocalConfigDeploymentAutoBuildData {
environment?: string[] environment?: string[]
} }
interface RsLocalConfigDeploymentPostActionData {
command?: string
scriptPath?: string
environment?: string[]
}
class RsLocalConfig { class RsLocalConfig {
private static instance: RsLocalConfig private static instance: RsLocalConfig
@ -57,4 +64,4 @@ class RsLocalConfig {
} }
} }
export { RsLocalConfig, type RsLocalConfigData } export { RsLocalConfig, type RsLocalConfigData, type RsLocalConfigDeploymentPostActionData }

View File

@ -60,7 +60,7 @@ func (v *Destination) GetType() DestinationType {
func (v *Destination) GetRawUri() (string, url.Values) { func (v *Destination) GetRawUri() (string, url.Values) {
uri := strings.SplitN(v.Uri, "://", 2)[1] uri := strings.SplitN(v.Uri, "://", 2)[1]
data := strings.SplitN(uri, "?", 2) 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]) qs, _ := url.ParseQuery(data[1])
return data[0], qs return data[0], qs

View File

@ -2,9 +2,12 @@ package sideload
import ( import (
"context" "context"
"fmt"
"git.solsynth.dev/goatworks/roadsign/pkg/warden" "git.solsynth.dev/goatworks/roadsign/pkg/warden"
"os" "os"
"os/exec"
"path/filepath" "path/filepath"
"strings"
"git.solsynth.dev/goatworks/roadsign/pkg/navi" "git.solsynth.dev/goatworks/roadsign/pkg/navi"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
@ -50,7 +53,7 @@ func doPublish(c *fiber.Ctx) error {
return fiber.ErrNotFound return fiber.ErrNotFound
} }
if c.Query("overwrite", "yes") == "yes" { if c.QueryBool("overwrite", true) {
files, _ := filepath.Glob(filepath.Join(workdir, "*")) files, _ := filepath.Glob(filepath.Join(workdir, "*"))
for _, file := range files { for _, file := range files {
_ = os.Remove(file) _ = os.Remove(file)
@ -74,6 +77,7 @@ func doPublish(c *fiber.Ctx) error {
return err return err
} }
} }
_ = os.Remove(dst)
default: default:
dst := filepath.Join(workdir, file.Filename) dst := filepath.Join(workdir, file.Filename)
if err := c.SaveFile(file, dst); err != nil { 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 { if instance != nil {
_ = instance.Wake() _ = instance.Wake()
} }

View File

@ -77,7 +77,7 @@ func doSync(c *fiber.Ctx) error {
_ = instance.Stop() _ = instance.Stop()
} }
for _, instance := range startQueue { for _, instance := range startQueue {
_ = instance.Start() _ = instance.Wake()
} }
return c.SendStatus(fiber.StatusOK) return c.SendStatus(fiber.StatusOK)

View File

@ -62,15 +62,9 @@ func (v *AppInstance) Wake() error {
} }
if v.Cmd.ProcessState.Exited() { if v.Cmd.ProcessState.Exited() {
return v.Start() 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 return nil
} }
}
func (v *AppInstance) Start() error { func (v *AppInstance) Start() error {
manifest := v.Manifest manifest := v.Manifest
@ -93,7 +87,7 @@ func (v *AppInstance) Start() error {
} else if v.Cmd != nil && v.Cmd.ProcessState == nil { } else if v.Cmd != nil && v.Cmd.ProcessState == nil {
v.Status = AppStarted v.Status = AppStarted
} else { } else {
v.Status = lo.Ternary(v.Cmd == nil, AppExited, AppFailure) v.Status = AppFailure
v.Cmd = nil v.Cmd = nil
return return
} }
@ -119,6 +113,7 @@ func (v *AppInstance) Stop() error {
} }
} }
v.Status = AppExited
return nil return nil
} }