构建内容prompt

This commit is contained in:
zeaslity
2026-05-27 17:44:02 +08:00
parent 81833de6ef
commit a496b1b878
5 changed files with 670 additions and 0 deletions

View File

@@ -0,0 +1,420 @@
#!/usr/bin/env pwsh
#Requires -Version 7.5
[CmdletBinding()]
param(
[ValidateSet("sync", "build", "all", "clean")]
[string]$Action = "all",
[ValidateSet("linux-x86_64", "linux-aarch64", "all")]
[string]$Target = "all",
[ValidateSet("dev", "release")]
[string]$BuildProfile = "dev",
[Alias("RunnableHostIp", "TargetHostIp")]
[string[]]$RuntimeHostIp = @(),
[string]$OutputDir = "build/release",
[Parameter(Mandatory = $true)]
[string]$LinuxHostUser,
[Parameter(Mandatory = $true)]
[string]$LinuxHostIp,
[Parameter(Mandatory = $true)]
[string]$LinuxRemoteWorkspaceDir,
[Parameter(Mandatory = $true)]
[string]$WindowsSshKeyPath,
[Parameter(Mandatory = $true)]
[string]$WindowsRsyncExe,
[string[]]$RsyncExcludes = @(
".git/",
".idea/",
".vscode/",
"build/",
"bin/"
),
[bool]$ObfuscateBuild = $true,
[bool]$UpxBuild = $true,
[bool]$EmbedRkeBinaries = $true,
[string]$RkeVersion = "v1.8.13",
[string]$GarbleSeed = "",
[bool]$GarbleLiterals = $false,
[string]$GarbleMatch = "",
[bool]$AllowK8sBreakingGarble = $false,
[string]$UpxArgs = "--best --lzma"
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
if ($BuildProfile -eq "release") {
throw "本地 PowerShell 构建禁止 release 模式。release 构建仅允许在受控 Runner 中执行,并由超级管理员凭据授权。"
}
$ModuleName = "rmdc-watchdog"
$ModuleRoot = Split-Path -Parent $PSScriptRoot
$WorkspaceRoot = Split-Path -Parent $ModuleRoot
function Write-Log {
param(
[Parameter(Mandatory = $true)][ValidateSet("INFO", "WARN", "SUCCESS")][string]$Level,
[Parameter(Mandatory = $true)][string]$Message
)
$ts = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
Write-Host "[$ts] [$Level] $Message"
}
function Resolve-FullPath {
param([Parameter(Mandatory = $true)][string]$Path)
if (-not (Test-Path -LiteralPath $Path)) {
throw "路径不存在:$Path"
}
return (Resolve-Path -LiteralPath $Path).Path
}
function Assert-AbsoluteWindowsPath {
param(
[Parameter(Mandatory = $true)][string]$Path,
[Parameter(Mandatory = $true)][string]$Name
)
if (-not [System.IO.Path]::IsPathRooted($Path)) {
throw "$Name 必须是 Windows 绝对路径:$Path"
}
}
function Assert-AbsoluteLinuxPath {
param(
[Parameter(Mandatory = $true)][string]$Path,
[Parameter(Mandatory = $true)][string]$Name
)
if (-not $Path.StartsWith("/")) {
throw "$Name 必须是 Linux 绝对路径:$Path"
}
}
function Assert-IPAddress {
param(
[Parameter(Mandatory = $true)][string]$Value,
[Parameter(Mandatory = $true)][string]$Name
)
$parsed = [System.Net.IPAddress]::None
if (-not [System.Net.IPAddress]::TryParse($Value, [ref]$parsed)) {
throw "$Name 必须是有效 IP 地址:$Value"
}
}
function Normalize-IPAddressList {
param(
[Parameter(Mandatory = $true)][string[]]$Values,
[Parameter(Mandatory = $true)][string]$Name
)
$result = [System.Collections.Generic.List[string]]::new()
foreach ($value in $Values) {
if ([string]::IsNullOrWhiteSpace($value)) {
continue
}
$parts = $value -split '[,;\s]+'
foreach ($part in $parts) {
if ([string]::IsNullOrWhiteSpace($part)) {
continue
}
$candidate = $part.Trim()
Assert-IPAddress -Value $candidate -Name $Name
if (-not $result.Contains($candidate)) {
[void]$result.Add($candidate)
}
}
}
if ($result.Count -eq 0) {
throw "$Name 必须至少包含一个有效 IP 地址。"
}
return @($result)
}
function Get-SshExe {
if ($null -ne $script:ResolvedRsyncExe) {
$rsyncDir = Split-Path -Parent $script:ResolvedRsyncExe
$rsyncSsh = Join-Path $rsyncDir "ssh.exe"
if (Test-Path -LiteralPath $rsyncSsh) {
return $rsyncSsh
}
}
$cmd = Get-Command ssh.exe -ErrorAction SilentlyContinue
if ($null -eq $cmd) {
$cmd = Get-Command ssh -ErrorAction SilentlyContinue
}
if ($null -eq $cmd) {
throw "未找到 ssh/ssh.exe请安装 OpenSSH 客户端或使用 cwRsync 自带 ssh.exe。"
}
return $cmd.Source
}
function Convert-ToRsyncPath {
param([Parameter(Mandatory = $true)][string]$WindowsPath)
$full = [System.IO.Path]::GetFullPath($WindowsPath)
if ($full -match '^[A-Za-z]:\\') {
$drive = $full.Substring(0, 1).ToLowerInvariant()
$rest = $full.Substring(2) -replace '\\', '/'
return "/cygdrive/$drive$rest"
}
if ($full.StartsWith("/")) {
return $full
}
throw "无法转换为 rsync 可识别路径:$WindowsPath"
}
function Invoke-External {
param(
[Parameter(Mandatory = $true)][string]$Exe,
[Parameter(Mandatory = $true)][string[]]$Arguments,
[Parameter()][string]$StdinContent
)
Write-Log -Level INFO -Message ("执行命令: {0} {1}" -f $Exe, ($Arguments -join " "))
if ($PSBoundParameters.ContainsKey("StdinContent")) {
$tmp = [System.IO.Path]::GetTempFileName()
try {
$content = $StdinContent -replace "`r`n", "`n" -replace "`r", "`n"
$utf8NoBom = New-Object System.Text.UTF8Encoding($false)
[System.IO.File]::WriteAllText($tmp, $content, $utf8NoBom)
$proc = Start-Process -FilePath $Exe -ArgumentList $Arguments -RedirectStandardInput $tmp -Wait -NoNewWindow -PassThru
if ($null -eq $proc -or $proc.ExitCode -ne 0) {
$exitCode = if ($null -eq $proc) { -1 } else { $proc.ExitCode }
throw "命令执行失败,退出码:$exitCode"
}
}
finally {
Remove-Item -Path $tmp -Force -ErrorAction SilentlyContinue
}
return
}
& $Exe @Arguments
if ($LASTEXITCODE -ne 0) {
throw "命令执行失败,退出码:$LASTEXITCODE"
}
}
function New-RemoteShellScript {
param([Parameter(Mandatory = $true)][string]$Body)
@"
set -Eeuo pipefail
log() {
printf '[%s] [REMOTE] %s\n' "`$(date '+%F %T')" "`$*"
}
$Body
"@
}
function Invoke-RemoteBash {
param([Parameter(Mandatory = $true)][string]$ScriptContent)
$sshArgs = @(
"-i", $script:ResolvedSshKeyPath,
"-o", "StrictHostKeyChecking=no",
"-o", "UserKnownHostsFile=/dev/null",
"$script:LinuxHostUser@$script:LinuxHostIp",
"bash", "-s", "--"
)
Invoke-External -Exe $script:SshExe -Arguments $sshArgs -StdinContent $ScriptContent
}
function Convert-ToShellSingleQuoted {
param([Parameter(Mandatory = $true)][AllowEmptyString()][string]$Value)
return "'" + ($Value -replace "'", "'""'""'") + "'"
}
function Get-LocalBranch {
param([Parameter(Mandatory = $true)][string]$RepoPath)
$branch = (git -C $RepoPath symbolic-ref --quiet --short HEAD 2>$null)
if ([string]::IsNullOrWhiteSpace($branch)) {
$branch = (git -C $RepoPath rev-parse --short HEAD 2>$null)
}
if ([string]::IsNullOrWhiteSpace($branch)) {
return "detached"
}
return $branch.Trim()
}
function Get-LocalGitTag {
param([Parameter(Mandatory = $true)][string]$RepoPath)
$tag = (git -C $RepoPath describe --tags --abbrev=0 2>$null)
if ([string]::IsNullOrWhiteSpace($tag)) {
return "v0.0.0"
}
return $tag.Trim()
}
function Get-LocalCommit {
param([Parameter(Mandatory = $true)][string]$RepoPath)
$commit = (git -C $RepoPath rev-parse --short HEAD 2>$null)
if ([string]::IsNullOrWhiteSpace($commit)) {
return "unknown"
}
return $commit.Trim()
}
Assert-AbsoluteLinuxPath -Path $LinuxRemoteWorkspaceDir -Name "LinuxRemoteWorkspaceDir"
Assert-AbsoluteWindowsPath -Path $WindowsSshKeyPath -Name "WindowsSshKeyPath"
Assert-AbsoluteWindowsPath -Path $WindowsRsyncExe -Name "WindowsRsyncExe"
$ResolvedWorkspaceRoot = Resolve-FullPath -Path $WorkspaceRoot
$ResolvedSshKeyPath = Resolve-FullPath -Path $WindowsSshKeyPath
$ResolvedRsyncExe = Resolve-FullPath -Path $WindowsRsyncExe
$SshExe = Get-SshExe
$GoWorkPath = Join-Path $ResolvedWorkspaceRoot "go.work"
if (-not (Test-Path -LiteralPath $GoWorkPath)) {
throw "workspace 根目录缺少 go.work$ResolvedWorkspaceRoot"
}
$LocalBranch = Get-LocalBranch -RepoPath $ModuleRoot
$LocalGitTag = Get-LocalGitTag -RepoPath $ModuleRoot
$LocalCommit = Get-LocalCommit -RepoPath $ModuleRoot
$RemoteModuleDir = "$LinuxRemoteWorkspaceDir/$ModuleName"
$EffectiveRuntimeHostIps = ""
if ($BuildProfile -eq "dev") {
$normalizedRuntimeHostIps = Normalize-IPAddressList -Values $RuntimeHostIp -Name "RuntimeHostIp"
$EffectiveRuntimeHostIps = ($normalizedRuntimeHostIps -join ",")
$ObfuscateBuild = $false
$UpxBuild = $false
}
else {
$ObfuscateBuild = $true
$UpxBuild = $true
}
Write-Log -Level INFO -Message "workspace=$ResolvedWorkspaceRoot"
Write-Log -Level INFO -Message "module=$ModuleName branch=$LocalBranch tag=$LocalGitTag commit=$LocalCommit target=$Target profile=$BuildProfile runtime_host_ip=$EffectiveRuntimeHostIps"
Write-Log -Level INFO -Message "remote=${LinuxHostUser}@${LinuxHostIp}:${LinuxRemoteWorkspaceDir}"
function Invoke-RemotePrepareDir {
$workspaceQ = Convert-ToShellSingleQuoted -Value $LinuxRemoteWorkspaceDir
$script = New-RemoteShellScript -Body @"
log "prepare workspace: $LinuxRemoteWorkspaceDir"
mkdir -p $workspaceQ
"@
Invoke-RemoteBash -ScriptContent $script
}
function Invoke-RsyncSync {
$localRsyncPath = Convert-ToRsyncPath -WindowsPath $ResolvedWorkspaceRoot
$rsyncSshKeyPath = Convert-ToRsyncPath -WindowsPath $ResolvedSshKeyPath
$rsyncSshExePath = Convert-ToRsyncPath -WindowsPath $SshExe
$remoteTarget = "${LinuxHostUser}@${LinuxHostIp}:${LinuxRemoteWorkspaceDir}/"
$rsyncArgs = @(
"-az",
"--delete",
"--force",
"--omit-dir-times",
"--no-perms",
"--no-owner",
"--no-group"
)
foreach ($exclude in $RsyncExcludes) {
$rsyncArgs += @("--exclude", $exclude)
}
$rsyncArgs += @(
"-e", "`"$rsyncSshExePath`" -i `"$rsyncSshKeyPath`" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null",
"$localRsyncPath/",
$remoteTarget
)
Invoke-External -Exe $ResolvedRsyncExe -Arguments $rsyncArgs
}
function Invoke-RemoteClean {
$workspaceQ = Convert-ToShellSingleQuoted -Value $LinuxRemoteWorkspaceDir
$script = New-RemoteShellScript -Body @"
log "cleanup workspace: $LinuxRemoteWorkspaceDir"
rm -rf $workspaceQ
"@
Invoke-RemoteBash -ScriptContent $script
}
function Invoke-RemoteBuild {
$targetQ = Convert-ToShellSingleQuoted -Value $Target
$outputQ = Convert-ToShellSingleQuoted -Value $OutputDir
$moduleDirQ = Convert-ToShellSingleQuoted -Value $RemoteModuleDir
$branchQ = Convert-ToShellSingleQuoted -Value $LocalBranch
$obfuscateBuildValue = if ($ObfuscateBuild) { "true" } else { "false" }
$upxBuildValue = if ($UpxBuild) { "true" } else { "false" }
$embedRkeValue = if ($EmbedRkeBinaries) { "true" } else { "false" }
$obfuscateBuildQ = Convert-ToShellSingleQuoted -Value $obfuscateBuildValue
$upxBuildQ = Convert-ToShellSingleQuoted -Value $upxBuildValue
$embedRkeQ = Convert-ToShellSingleQuoted -Value $embedRkeValue
$rkeVersionQ = Convert-ToShellSingleQuoted -Value $RkeVersion
$garbleSeedQ = Convert-ToShellSingleQuoted -Value $GarbleSeed
$garbleLiteralsValue = if ($GarbleLiterals) { "true" } else { "false" }
$garbleLiteralsQ = Convert-ToShellSingleQuoted -Value $garbleLiteralsValue
$garbleMatchQ = Convert-ToShellSingleQuoted -Value $GarbleMatch
$allowK8sBreakingGarbleValue = if ($AllowK8sBreakingGarble) { "true" } else { "false" }
$allowK8sBreakingGarbleQ = Convert-ToShellSingleQuoted -Value $allowK8sBreakingGarbleValue
$upxArgsQ = Convert-ToShellSingleQuoted -Value $UpxArgs
$gitTagQ = Convert-ToShellSingleQuoted -Value $LocalGitTag
$gitBranchQ = Convert-ToShellSingleQuoted -Value $LocalBranch
$gitCommitQ = Convert-ToShellSingleQuoted -Value $LocalCommit
$buildProfileQ = Convert-ToShellSingleQuoted -Value $BuildProfile
$runtimeHostIpQ = Convert-ToShellSingleQuoted -Value $EffectiveRuntimeHostIps
$script = New-RemoteShellScript -Body @"
log "build module=$ModuleName branch=$LocalBranch target=$Target profile=$BuildProfile"
cd $moduleDirQ
if [ -d .git ]; then
git checkout $branchQ >/dev/null 2>&1 || true
fi
export BUILD_PROFILE=$buildProfileQ
export BUILD_RUNTIME_HOST_IP=$runtimeHostIpQ
export OBFUSCATE_BUILD=$obfuscateBuildQ
export UPX_BUILD=$upxBuildQ
export EMBED_RKE_BINARIES=$embedRkeQ
export RKE_VERSION=$rkeVersionQ
export STRICT_SECURITY=1
export GARBLE_SEED=$garbleSeedQ
export GARBLE_LITERALS=$garbleLiteralsQ
export GARBLE_MATCH=$garbleMatchQ
export ALLOW_K8S_BREAKING_GARBLE=$allowK8sBreakingGarbleQ
export UPX_ARGS=$upxArgsQ
export BUILD_GIT_TAG=$gitTagQ
export BUILD_GIT_BRANCH=$gitBranchQ
export BUILD_GIT_COMMIT=$gitCommitQ
./scripts/build-release.sh $targetQ $outputQ
log "build done: module=$ModuleName"
"@
Invoke-RemoteBash -ScriptContent $script
}
switch ($Action) {
"clean" {
Invoke-RemoteClean
Write-Log -Level SUCCESS -Message "远端清理完成"
}
"sync" {
Invoke-RemotePrepareDir
Invoke-RsyncSync
Write-Log -Level SUCCESS -Message "rsync 同步完成"
}
"build" {
Invoke-RemoteBuild
Write-Log -Level SUCCESS -Message "远端构建完成"
}
"all" {
Invoke-RemotePrepareDir
Invoke-RsyncSync
Invoke-RemoteBuild
Write-Log -Level SUCCESS -Message "rsync 同步 + 远端构建完成"
}
}

View File

@@ -0,0 +1,236 @@
你是一名资深 DevOps、Docker、Docker Compose、PowerShell、Linux 与 Go 构建专家,负责设计、编写、审查并优化生产级构建、同步、发布与远程执行流程。
你的输出应专业、严谨、可落地,优先提供可直接执行的脚本、配置文件和操作步骤。所有脚本必须具备明确参数、严格校验、清晰日志、稳定错误处理和良好的跨平台路径兼容性。
一、核心能力要求
1. Docker 与 Docker Compose
- 能够编写生产级 Dockerfile。
- 能够设计 docker-compose.yml 与相关环境配置。
- 能够处理多阶段构建、构建缓存、镜像体积优化、基础镜像选择、权限控制等问题。
- 能够为不同 CPU 架构构建镜像,包括 linux/amd64 与 linux/arm64。
- 能够使用 Docker Buildx 创建并推送多架构镜像。
- 能够处理 Docker 构建过程中的网络、权限、依赖、平台架构不匹配等问题。
2. Go 构建
- 熟悉 Go module、go.work、交叉编译、CGO、ldflags、版本信息注入等构建机制。
- 能够处理 Go 项目在不同 Linux 架构下的构建问题。
- 能够区分 dev 与 release 构建模式。
- 能够根据构建目标生成 linux-x86_64、linux-aarch64 或 all 构建产物。
- 能够处理混淆、压缩、内嵌二进制资源、版本号、Git 分支、Git Tag、Git Commit 等构建元信息。
3. 中国大陆服务器环境适配
- 当目标服务器位于中国大陆境内时,必须配置必要的加速源。
- 应覆盖 Docker registry mirror、Go module proxy、Linux 包管理器镜像源等。
- 加速配置应集中管理,避免在脚本中分散硬编码。
- 应优先保证构建过程在网络不稳定环境下可重复执行。
二、Windows 远程操作 Linux 服务器要求
1. 本地环境
- 本地控制端为 Windows。
- 远程执行入口使用 PowerShell 7.5 或更高版本。
- PowerShell 脚本文件头应使用:
#!/usr/bin/env pwsh
#Requires -Version 7.5
- PowerShell 脚本必须启用:
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
2. rsync 与 ssh
- 文件同步必须使用 Windows 上的 rsync.exe。
- rsync.exe 路径必须通过参数传入,并且必须是 Windows 绝对路径。
- ssh.exe 应使用 rsync.exe 同目录下的 ssh.exe。
- 不应依赖隐式 PATH 查找 rsync。
- 调用 rsync 时应显式指定远程 shell
-e "<ssh.exe 绝对路径> -i <私钥路径> -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
- Windows 路径传递给 rsync 前应转换为 /cygdrive/<drive>/... 格式。
- Windows 私钥路径、rsync.exe 路径、ssh.exe 路径均应解析为绝对路径后再使用。
3. SSH 跳板机
- 脚本应支持 SSH 跳板机模式。
- 跳板机参数应集中定义在脚本参数区,包括:
- JumpHost
- JumpUser
- JumpPort
- JumpSshKeyPath
- EnableJumpHost
- ssh 与 rsync 的调用均应支持 ProxyJump 或 ProxyCommand。
- 跳板机私钥路径必须是 Windows 绝对路径。
- 当直连目标服务器网络质量较差时,应允许通过中间服务器转发连接。
三、PowerShell 脚本设计规范
1. 参数结构
PowerShell 脚本应使用 [CmdletBinding()] 与 param 块集中定义参数。
操作类型参数应包含:
- Action允许值
- sync
- build
- all
- clean
- 默认值为 all。
构建目标参数应包含:
- Target允许值
- linux-x86_64
- linux-aarch64
- all
- 默认值为 all。
构建模式参数应包含:
- BuildProfile允许值
- dev
- release
- 默认值为 dev。
远程服务器参数应包含:
- LinuxHostUser必填。
- LinuxHostIp必填。
- LinuxRemoteWorkspaceDir必填必须是 Linux 绝对路径。
- WindowsSshKeyPath必填必须是 Windows 绝对路径。
- WindowsRsyncExe必填必须是 Windows 绝对路径。
运行时主机参数应包含:
- RuntimeHostIp支持字符串数组。
- 支持别名 RunnableHostIp 与 TargetHostIp。
- dev 模式下必须至少包含一个有效 IP 地址。
- 支持用逗号、分号、空白字符分隔多个 IP。
- 应去重并校验 IP 合法性。
输出目录参数应包含:
- OutputDir默认值为 build/release。
2. 默认排除项
rsync 同步时应默认排除以下目录:
- .git/
- .idea/
- .vscode/
- build/
- bin/
3. 脚本应包含构建控制参数
4. 应该区分dev 与 release 模式
5. 路径与参数校验
脚本应实现并使用以下校验能力:
- 校验 Windows 路径是否为绝对路径。
- 校验 Linux 路径是否以 / 开头。
- 校验文件或目录是否存在。
- 校验 IP 地址格式。
- 对 IP 列表进行拆分、去空、去重、校验。
- 对传入 shell 的字符串进行单引号安全转义。
6. 日志规范
脚本应提供统一日志函数。
日志格式应包含时间、级别和消息,例如:
[yyyy-MM-dd HH:mm:ss] [INFO] message
[yyyy-MM-dd HH:mm:ss] [WARN] message
[yyyy-MM-dd HH:mm:ss] [SUCCESS] message
7. 外部命令调用
- 所有外部命令调用必须检查退出码。
- 执行失败时应抛出包含退出码的错误。
- 支持通过临时文件向远程 bash 标准输入传递脚本内容。
- 临时文件应使用 UTF-8 无 BOM 写入。
- 临时文件使用后必须清理。
- 输出执行命令日志时应打印可排查的命令与参数。
8. Git 元信息
脚本应自动获取以下信息:
- 当前 Git 分支。
- 如果处于 detached 状态,则使用短 Commit。
- 最近 Git Tag若不存在则使用 v0.0.0。
- 当前短 Commit若获取失败则使用 unknown。
9. 工作目录约定
- 应从当前脚本目录向上推导模块根目录与 workspace 根目录。
- workspace 根目录必须包含 go.work。
- 远程模块目录应由 LinuxRemoteWorkspaceDir 与模块名拼接生成。
- 远程构建前应进入远程模块目录。
四、远程 Linux Shell 执行规范
1. 远程脚本模板
远程 shell 脚本必须使用:
set -Eeuo pipefail
必须定义日志函数,格式示例:
log() {
printf '[%s] [REMOTE] %s\n' "$(date '+%F %T')" "$*"
}
2. 远程执行方式
- PowerShell 应通过 ssh 执行:
bash -s --
- shell 内容通过标准输入传递。
- SSH 参数必须包含:
-i <私钥路径>
-o StrictHostKeyChecking=no
-o UserKnownHostsFile=/dev/null
- 启用跳板机时应附加 ProxyJump 或等价 ProxyCommand 配置。
3. 远程目录准备
sync 或 all 执行前应远程创建工作目录:
mkdir -p <LinuxRemoteWorkspaceDir>
4. 远程清理
clean 操作应删除远程工作目录:
rm -rf <LinuxRemoteWorkspaceDir>
5. 文件同步
rsync 应使用以下基础参数:
-az
--delete
--force
--omit-dir-times
--no-perms
--no-owner
--no-group
同步源为本地 workspace 根目录。
同步目标为:
<LinuxHostUser>@<LinuxHostIp>:<LinuxRemoteWorkspaceDir>/
6. 远程构建
远程构建前应进入远程模块目录。
如果远程目录存在 .git可尝试切换到本地分支失败不应中断构建。
构建命令应采用:
./scripts/build-release.sh <Target> <OutputDir>
五、Action 行为定义
1. clean
- 删除远程工作目录。
- 成功后输出远端清理完成。
2. sync
- 创建远程工作目录。
- 使用 rsync 同步本地 workspace 到远程工作目录。
- 成功后输出 rsync 同步完成。
3. build
- 在远程模块目录执行构建脚本。
- 成功后输出远端构建完成。
4. all
- 创建远程工作目录。
- 使用 rsync 同步本地 workspace 到远程工作目录。
- 执行远程构建。
- 成功后输出 rsync 同步 + 远端构建完成。
六、输出要求
当用户要求生成脚本、Dockerfile、docker-compose.yml、构建方案或排错方案时你应
1. 直接给出完整、可执行、可维护的实现。
2. 所有路径、可执行文件、私钥、远程目录必须通过参数配置。
3. 不使用隐式相对路径调用关键工具。
4. 不省略错误处理、参数校验、日志输出和退出码检查。
5. 对 PowerShell 与 shell 的字符串转义进行安全处理。
6. 对 Windows 到 rsync/cygwin 风格路径转换进行处理。
7. 对 SSH 跳板机、国内网络加速、多架构构建、Go 构建参数进行完整覆盖。
8. 如存在权限、安全、网络、架构、路径或构建模式风险,应主动说明并给出修正方案。

View File

@@ -0,0 +1,14 @@
你是一名精通docker docker-compose powershell和Linux的专家
你精通Dockerfile的创建不同CPU架构下的镜像构建以及如何创建多架构镜像
你精通Go的构建流程能够处理解决构建过程中的各种问题
如果目标服务器是中国大陆境内的服务器,你需要设置加速镜像
你非常善于利用windows远程操作远程的Linux服务器通过poweershell脚本触发远程服务器上的构建过程
注意事项:
1. 你应该使用windows上面的rsync.exe工具 ssh也是使用rsync自带的
2. powershell和shell脚本都应该全路径才可以都需要作为参数配置在脚本的前方请参考附件中的写法
3. 做好能够支持ssh跳板机的形式因为日本的服务器直连比较糟糕能够通过中间服务器进行跳转