fix & feat: 改了数据库发布的bug,单脚本前端完成
- local server 前端页面
This commit is contained in:
parent
84ba994048
commit
f47975af06
4 changed files with 213 additions and 91 deletions
|
@ -211,7 +211,7 @@ public class FileDirOpForUnpack(string srcRootPath, string dstRootPath) : FileDi
|
||||||
ZipEntry theEntry;
|
ZipEntry theEntry;
|
||||||
while ((theEntry = s.GetNextEntry()) != null)
|
while ((theEntry = s.GetNextEntry()) != null)
|
||||||
{
|
{
|
||||||
Console.WriteLine(theEntry.Name);
|
//Console.WriteLine(theEntry.Name);
|
||||||
|
|
||||||
string directoryName =
|
string directoryName =
|
||||||
dstPath + $"/{Id}/" + Path.GetDirectoryName(theEntry.Name)
|
dstPath + $"/{Id}/" + Path.GetDirectoryName(theEntry.Name)
|
||||||
|
|
|
@ -6,7 +6,6 @@ using Common;
|
||||||
|
|
||||||
namespace RemoteServer;
|
namespace RemoteServer;
|
||||||
|
|
||||||
|
|
||||||
public abstract class StateHelpBase(
|
public abstract class StateHelpBase(
|
||||||
RemoteSyncServer context,
|
RemoteSyncServer context,
|
||||||
SyncProcessStep step = SyncProcessStep.Connect
|
SyncProcessStep step = SyncProcessStep.Connect
|
||||||
|
@ -132,7 +131,11 @@ public class UnPackAndReleaseHelper(RemoteSyncServer context)
|
||||||
Context.Pipe.SendMsg(CreateMsg("解压完成!")).Wait();
|
Context.Pipe.SendMsg(CreateMsg("解压完成!")).Wait();
|
||||||
var h = new FinallyPublishHelper(Context);
|
var h = new FinallyPublishHelper(Context);
|
||||||
Context.SetStateHelpBase(h);
|
Context.SetStateHelpBase(h);
|
||||||
|
Context.Pipe.SendMsg(h.CreateMsg("将要发布数据库,可能时间会较长!")).Wait();
|
||||||
|
Task.Run(() =>
|
||||||
|
{
|
||||||
h.FinallyPublish();
|
h.FinallyPublish();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void HandleMsg(SyncMsg msg) { }
|
protected override void HandleMsg(SyncMsg msg) { }
|
||||||
|
@ -144,10 +147,10 @@ public class FinallyPublishHelper(RemoteSyncServer context)
|
||||||
public void FinallyPublish()
|
public void FinallyPublish()
|
||||||
{
|
{
|
||||||
// 发布数据库
|
// 发布数据库
|
||||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
if (Context.NotNullSyncConfig.IsDeployDb)
|
||||||
{
|
{
|
||||||
var arguments =
|
var arguments =
|
||||||
$" /Action:Publish /SourceFile:{RemoteSyncServer.TempRootFile}/{Context.NotNullSyncConfig.Id}/{Context.NotNullSyncConfig.Id}.dacpac"
|
$" /Action:Publish /SourceFile:{RemoteSyncServer.TempRootFile}/{Context.NotNullSyncConfig.Id.ToString()}/{Context.NotNullSyncConfig.Id}.dacpac"
|
||||||
+ $" /TargetServerName:{Context.NotNullSyncConfig.DstDb.ServerName} /TargetDatabaseName:{Context.NotNullSyncConfig.DstDb.DatebaseName}"
|
+ $" /TargetServerName:{Context.NotNullSyncConfig.DstDb.ServerName} /TargetDatabaseName:{Context.NotNullSyncConfig.DstDb.DatebaseName}"
|
||||||
+ $" /TargetUser:{Context.NotNullSyncConfig.DstDb.User} /TargetPassword:{Context.NotNullSyncConfig.DstDb.Password} /TargetTrustServerCertificate:True";
|
+ $" /TargetUser:{Context.NotNullSyncConfig.DstDb.User} /TargetPassword:{Context.NotNullSyncConfig.DstDb.Password} /TargetTrustServerCertificate:True";
|
||||||
|
|
||||||
|
@ -155,6 +158,7 @@ public class FinallyPublishHelper(RemoteSyncServer context)
|
||||||
new()
|
new()
|
||||||
{
|
{
|
||||||
StandardOutputEncoding = System.Text.Encoding.UTF8,
|
StandardOutputEncoding = System.Text.Encoding.UTF8,
|
||||||
|
Arguments = arguments,
|
||||||
FileName = RemoteSyncServer.SqlPackageAbPath, // The command to execute (can be any command line tool)
|
FileName = RemoteSyncServer.SqlPackageAbPath, // The command to execute (can be any command line tool)
|
||||||
// The arguments to pass to the command (e.g., list directory contents)
|
// The arguments to pass to the command (e.g., list directory contents)
|
||||||
RedirectStandardOutput = true, // Redirect the standard output to a string
|
RedirectStandardOutput = true, // Redirect the standard output to a string
|
||||||
|
|
1
Tool/JsScript/package.json
Normal file
1
Tool/JsScript/package.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{ "dependencies": { "chalk": "^5.3.0", "ws": "^8.18.0" } }
|
|
@ -1,44 +1,123 @@
|
||||||
import chalk from "chalk";
|
import chalk from "chalk";
|
||||||
import WebSocket from "ws";
|
import WebSocket from "ws";
|
||||||
|
|
||||||
|
|
||||||
//#region ############################## 配置文件 ###################################
|
//#region ############################## 配置文件 ###################################
|
||||||
|
|
||||||
|
const LocalHost = "127.0.0.1";
|
||||||
//这是个例子,请在`config`中写你的配置
|
//这是个例子,请在`config`中写你的配置
|
||||||
const example_config = {
|
const example_config = {
|
||||||
//发布的项目名称,它的目的是为了防止有两个人同时发布一个项目,和便于排查发布历史记录
|
//发布的名称,每个项目具有唯一的一个名称
|
||||||
Name: "",
|
Name: "Test",
|
||||||
//发布服务器的地址
|
RemotePwd: "t123",
|
||||||
RemoteUrl: "http://192.168.1.100:8067",
|
//远程服务器地址,也就是发布的目的地,它是正式环境
|
||||||
//源SqlServer数据库的链接字符串,一般是开发或者测试数据库,**此数据库的ip是相对于运行此脚本的机器**
|
RemoteUrl: "127.0.0.1:6819",
|
||||||
SrcDbConnection: "",
|
//是否发布数据库 sqlserver
|
||||||
//目的SqlServer数据库的链接字符串,一般是正式环境数据库,**此数据库的ip是相对于运行RemoteServer的机器**
|
IsDeployDb: false,
|
||||||
DstDbConnection: "",
|
//是否发布前重新构建项目
|
||||||
|
IsDeployProject: false,
|
||||||
//发布数据库时,只同步结构。此数组中的表,将会连数据也一起同步
|
//项目地址
|
||||||
SyncDataTables:[],
|
LocalProjectAbsolutePath:
|
||||||
|
"D:/git/HMES-H7-HNFY/HMES-H7-HNFYMF/HMES-H7-HNFYMF.WEB",
|
||||||
//源文件目录地址,是要发布的文件根目录,它是绝对路径,!执行发布时将发布到这个目录!
|
//源文件目录地址,是要发布的文件根目录,它是绝对路径,!执行发布时将发布到这个目录!
|
||||||
LocalRootPath: "",
|
LocalRootPath: "D:/FileSyncTest/src",
|
||||||
//目标文件目录地址,也就是部署服务的机器上的项目文件根目录,它是绝对路径
|
//目标文件目录地址,也就是部署服务的机器上的项目文件根目录,它是绝对路径
|
||||||
RemoteRootPath: "",
|
RemoteRootPath: "D:/FileSyncTest/dst",
|
||||||
|
//源数据库配置 SqlServer,将会同步数据库的结构
|
||||||
//根目录下的子目录,分子目录是为了针对不同的目录有不同的发布策略,它是相对路径,即相对于LocalRootPath和RemoteRootPath,文件数据依此进行
|
SrcDb: {
|
||||||
|
//Host
|
||||||
|
ServerName: "172.16.12.2",
|
||||||
|
//数据库名
|
||||||
|
DatebaseName: "HMES_H7_HNFYMF",
|
||||||
|
User: "hmes-h7",
|
||||||
|
Password: "Hmes-h7666",
|
||||||
|
//是否信任服务器证书
|
||||||
|
TrustServerCertificate: "True",
|
||||||
|
//同步的数据,这些数据将会同步
|
||||||
|
SyncTablesData: [
|
||||||
|
"dbo.sys_Button",
|
||||||
|
"dbo.sys_Menu",
|
||||||
|
"dbo.sys_Module",
|
||||||
|
"dbo.sys_Page",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
//目标数据库配置 sqlserver
|
||||||
|
DstDb: {
|
||||||
|
ServerName: "127.0.0.1",
|
||||||
|
DatebaseName: "HMES_H7_HNFYMF",
|
||||||
|
User: "sa",
|
||||||
|
Password: "0",
|
||||||
|
TrustServerCertificate: "True",
|
||||||
|
},
|
||||||
|
//子目录配置,每个子目录都有自己不同的发布策略,它是相对路径,即相对于LocalRootPath和RemoteRootPath(注意 '/',这将拼成一个完整的路径),文件数据依此进行,
|
||||||
DirFileConfigs: [
|
DirFileConfigs: [
|
||||||
{
|
{
|
||||||
//子目录的相对路径
|
DirPath: "/bin",
|
||||||
DirPath: "",
|
|
||||||
//排除的文件或目录,它是相对路径,相对于!!!LocalRootPath和RemoteRootPath!!!
|
//排除的文件或目录,它是相对路径,相对于!!!LocalRootPath和RemoteRootPath!!!
|
||||||
Excludes: [],
|
Excludes: ["/roslyn", "/Views"],
|
||||||
//只追踪文件或目录,它是相对路径,相对于!!!LocalRootPath和RemoteRootPath!!!,它的优先级最高,如果你指定了它的值,Excludes将会失效
|
//只追踪文件或目录,它是相对路径,相对于!!!LocalRootPath和RemoteRootPath!!!,它的优先级最高,如果你指定了它的值,Excludes将会失效
|
||||||
CherryPicks: [],
|
// CherryPicks:[]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const config = {
|
||||||
|
//发布的名称,每个项目具有唯一的一个名称
|
||||||
|
Name: "Test",
|
||||||
|
RemotePwd: "t123",
|
||||||
|
//远程服务器地址,也就是发布的目的地,它是正式环境
|
||||||
|
RemoteUrl: "127.0.0.1:6819",
|
||||||
|
//是否发布数据库 sqlserver
|
||||||
|
IsDeployDb: true,
|
||||||
|
//是否发布前重新构建项目
|
||||||
|
IsDeployProject: true,
|
||||||
|
//项目地址
|
||||||
|
LocalProjectAbsolutePath:
|
||||||
|
"D:/git/HMES-H7-HNFY/HMES-H7-HNFYMF/HMES-H7-HNFYMF.WEB",
|
||||||
|
//源文件目录地址,是要发布的文件根目录,它是绝对路径,!执行发布时将发布到这个目录!
|
||||||
|
LocalRootPath: "D:/FileSyncTest/src",
|
||||||
|
//目标文件目录地址,也就是部署服务的机器上的项目文件根目录,它是绝对路径
|
||||||
|
RemoteRootPath: "D:/FileSyncTest/dst",
|
||||||
|
//源数据库配置 SqlServer,将会同步数据库的结构
|
||||||
|
SrcDb: {
|
||||||
|
//Host
|
||||||
|
ServerName: "172.16.12.2",
|
||||||
|
//数据库名
|
||||||
|
DatebaseName: "HMES_H7_HNFYMF",
|
||||||
|
User: "hmes-h7",
|
||||||
|
Password: "Hmes-h7666",
|
||||||
|
//是否信任服务器证书
|
||||||
|
TrustServerCertificate: "True",
|
||||||
|
//同步的数据,这些数据将会同步
|
||||||
|
SyncTablesData: [
|
||||||
|
"dbo.sys_Button",
|
||||||
|
"dbo.sys_Menu",
|
||||||
|
"dbo.sys_Module",
|
||||||
|
"dbo.sys_Page",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
//目标数据库配置 sqlserver
|
||||||
|
DstDb: {
|
||||||
|
ServerName: "127.0.0.1",
|
||||||
|
DatebaseName: "HMES_H7_HNFYMF",
|
||||||
|
User: "sa",
|
||||||
|
Password: "0",
|
||||||
|
TrustServerCertificate: "True",
|
||||||
|
},
|
||||||
|
//子目录配置,每个子目录都有自己不同的发布策略,它是相对路径,即相对于LocalRootPath和RemoteRootPath(注意 '/',这将拼成一个完整的路径),文件数据依此进行,
|
||||||
|
DirFileConfigs: [
|
||||||
|
{
|
||||||
|
DirPath: "/bin",
|
||||||
|
//排除的文件或目录,它是相对路径,相对于!!!LocalRootPath和RemoteRootPath!!!
|
||||||
|
Excludes: ["/roslyn", "/Views"],
|
||||||
|
//只追踪文件或目录,它是相对路径,相对于!!!LocalRootPath和RemoteRootPath!!!,它的优先级最高,如果你指定了它的值,Excludes将会失效
|
||||||
|
// CherryPicks:[]
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
const config = {};
|
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
//#region ############################## 打印函数 ###################################
|
//#region ############################## 打印函数 ###################################
|
||||||
|
|
||||||
|
let IsSuccess = false;
|
||||||
/**
|
/**
|
||||||
* 在新行打印错误信息
|
* 在新行打印错误信息
|
||||||
*/
|
*/
|
||||||
|
@ -62,9 +141,12 @@ function PrintSuccessInNewLine(str) {
|
||||||
/**
|
/**
|
||||||
* 在新行打印一般信息
|
* 在新行打印一般信息
|
||||||
*/
|
*/
|
||||||
function PrintGeneralInNewLine(str) {
|
function PrintCloseNewLine(str) {
|
||||||
process.stdout.write("\n");
|
if(IsSuccess) {
|
||||||
process.stdout.write(str);
|
PrintSuccessInNewLine(str)
|
||||||
|
} else {
|
||||||
|
PrintErrInNewLine(str)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 在当前行打印一般信息,打印此行信息之前会清除当前行
|
* 在当前行打印一般信息,打印此行信息之前会清除当前行
|
||||||
|
@ -80,36 +162,71 @@ function PrintGeneralInCurrentLine(str) {
|
||||||
/**
|
/**
|
||||||
* 1-n. localServer 工作,此处只展示信息
|
* 1-n. localServer 工作,此处只展示信息
|
||||||
*/
|
*/
|
||||||
|
let ws = null;
|
||||||
//这个是固定死的
|
function MsgCb(MsgIt) {
|
||||||
const wsUrl = `ws://127.0.0.1:4538/websoc?Name=${config.Name}`;
|
if (MsgIt.Type == 2) {
|
||||||
const ws = new WebSocket(wsUrl);
|
PrintGeneralInCurrentLine(MsgIt.Body);
|
||||||
|
|
||||||
ws.on('open', () => {
|
|
||||||
//上传配置
|
|
||||||
ws.send(JSON.stringify(config),(err)=>{
|
|
||||||
console.log(err)
|
|
||||||
ws.close()
|
|
||||||
})
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
ws.on('message', (message) => {
|
|
||||||
var msg = message.toString('utf8')
|
|
||||||
DealMsg(msg)
|
|
||||||
});
|
|
||||||
|
|
||||||
ws.on('close', () => {
|
|
||||||
});
|
|
||||||
|
|
||||||
function DealMsg(str) {
|
|
||||||
var msg = JSON.parse(str)
|
|
||||||
if(msg.IsSuccess) {
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
PrintErrInNewLine(msg.Body)
|
if (MsgIt.Step <= 6) {
|
||||||
ws.close()
|
PrintSuccessInNewLine(`(${MsgIt.Step}/6) ${MsgIt.Body}`);
|
||||||
|
if (MsgIt.Step == 6) {
|
||||||
|
if (MsgIt.Body == "发布完成!") {
|
||||||
|
IsSuccess = true
|
||||||
|
ws.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(MsgIt == 7) {
|
||||||
|
PrintErrInNewLine(MsgIt.Body);
|
||||||
|
} else {
|
||||||
|
PrintCloseNewLine("(关闭)"+ MsgIt.Body);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
async function connectWebSocket() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const wsUrl = `ws://${LocalHost}:6818/websoc?Name=${config.Name}`;
|
||||||
|
ws = new WebSocket(wsUrl);
|
||||||
|
|
||||||
|
ws.onopen = (event) => {
|
||||||
|
var starter = {
|
||||||
|
Body: JSON.stringify(config),
|
||||||
|
Type: 1,
|
||||||
|
Step: 1,
|
||||||
|
};
|
||||||
|
// console.warn("websocket connected!");
|
||||||
|
ws.send(JSON.stringify(starter));
|
||||||
|
};
|
||||||
|
ws.onmessage = (event) => {
|
||||||
|
// console.log(event.data);
|
||||||
|
MsgCb(JSON.parse(event.data));
|
||||||
|
};
|
||||||
|
ws.onclose = (event) => {
|
||||||
|
// console.warn(event)
|
||||||
|
MsgCb({
|
||||||
|
Type: 0,
|
||||||
|
Step: 8,
|
||||||
|
Body: event.reason,
|
||||||
|
});
|
||||||
|
// resolve()
|
||||||
|
};
|
||||||
|
ws.onerror = (e) => {
|
||||||
|
// console.error(e);
|
||||||
|
MsgCb({
|
||||||
|
Type: 0,
|
||||||
|
Body: "异常错误,查看 Console",
|
||||||
|
Step: 7,
|
||||||
|
});
|
||||||
|
reject(err);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
(async function main() {
|
||||||
|
try {
|
||||||
|
await connectWebSocket();
|
||||||
|
// console.log('WebSocket has closed');
|
||||||
|
// The script will wait here until the WebSocket connection is closed
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Failed to connect or an error occurred:", err);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
Loading…
Reference in a new issue