代码改变世界

天行健,君子以自强不息

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

简介

Gitlab Runner在Windows上运行之后,我们在.gitlab-ci.yml中编写script语句,思路和Linux是一样。但是考虑到Windows的特点,为了让程序员少接触一些知识点,以及给未来执行作业的时候预留更多的操作空间。简单说就是未来修改执行作业时候的逻辑,但是每个软件仓库根目录下的.gitlab-ci.yml不需要改动,我们一共编写了6个PowerShell脚本,和1个适配Directory.Build.props技术的windows批处理文件。

这里有两个PowerShell,一个是在Windows Gitlab Runner服务器上运行,另外一个是在Web应用程序服务器上运行。前者调用后者。

1、Gitlab Runner服务器上的PowerShell

# 设置环境变量以支持UTF-8编码
param (
	[Parameter(Mandatory=$true)]
	[string]$ssh_rsa_file,
	[Parameter(Mandatory=$true)]
	[string]$web_output_path,
	[Parameter(Mandatory=$true)]
	[string]$remote_username,
	[Parameter(Mandatory=$true)]
	[string]$remote_server,
	[Parameter(Mandatory=$true)]
	[string]$remote_root_dir_name,
	[Parameter(Mandatory=$true)]
	[string]$remote_site_name,
	[Parameter(Mandatory=$true)]
	[string]$remote_windows_web_app_pool,
	[Parameter(Mandatory=$true)]
	[string]$web_app_name,
	[Parameter(Mandatory=$true)]
	[string]$version_id
)
chcp 65001
 
$version_id = $version_id.Replace('.','_') 

# 确保所有参数值中的特殊字符被适当转义,特别是对于包含在路径或字符串中的双引号
$escapedSiteName = $remote_site_name -replace "'", "''"
$escapedPool = $remote_windows_web_app_pool -replace "'", "''"
$escapedAppName = $web_app_name -replace "'", "''"
$escapedVersion = $version_id -replace "'", "''"

$remote_script_path = "c:\welcome-gitlab-runner\Setup-WebApp.ps1"

# 构建远程脚本调用的参数字符串,保持简单并确保参数间以空格分隔
$remoteParams = "-remote_site_name '$escapedSiteName' -remote_windows_web_app_pool '$escapedPool' -web_app_name '$escapedAppName' -version_id '$escapedVersion'"

# 构建完整的SSH命令,注意引号的正确使用和转义
$sshCmd = "ssh -i `"$ssh_rsa_file`" -o ""StrictHostKeyChecking=no"" -v `"$remote_username@$remote_server`" 'powershell.exe -ExecutionPolicy Bypass -File `"$remote_script_path`" $remoteParams'"
# 注意:$remote_script_path 应替换为实际的远程脚本路径,如"c:\for-gitlab-runner\Setup-LodaWebApp.ps1"

# 打印命令以供调试
Write-Host "Executing Command: $sshCmd"

# 执行SSH命令
Invoke-Expression $sshCmd


if ($LASTEXITCODE -ne 0)  {
	if ($Errors.Count -gt 0) {
    Write-Host "清空远程目录时出错:" $Errors[0].Exception.Message
    Write-Host "错误信息:" $Errors[0].Exception.Message
    Write-Host "堆栈跟踪:" $Errors[0].Exception.StackTrace
}
else {
    Write-Host "没有错误信息记录。"
}
}
$remote_dir = "C:\" + $remote_root_dir_name + "\" + $web_app_name + "\" + $version_id
scp -i $ssh_rsa_file -o StrictHostKeyChecking=no -rv ${web_output_path}"\*" ${remote_username}@${remote_server}:$remote_dir

Exit $LASTEXITCODE

2、Web应用程序服务器上的PowerShell

根据前边脚本的内容,

$remote_script_path = "c:\welcome-gitlab-runner\Setup-WebApp.ps1"

可以知道我们这个脚本,要放置在Web应用程序服务器的对应位置。

内容如下:

param(
    [Parameter(Mandatory=$true)]
    [string]$remote_site_name,
    [Parameter(Mandatory=$true)]
    [string]$remote_windows_web_app_pool,
    [Parameter(Mandatory=$true)]
    [string]$web_app_name,
    [Parameter(Mandatory=$true)]
    [string]$version_id
)

chcp 65001

Write-Host "已绑定的参数及其值:"
$PSBoundParameters.GetEnumerator() | ForEach-Object {
    Write-Host "$($_.Key): $($_.Value)"
}
$version_id = $version_id.Replace('.','_')

$AppPhysicalPath = "C:\loda\" + ${web_app_name} + "\" + $version_id
New-Item -Path $AppPhysicalPath -ItemType Directory -Force

# 定义IIS PowerShell模块路径,根据实际情况调整
$IISModulePath = "C:\Windows\System32\WindowsPowerShell\v1.0\Modules\WebAdministration\WebAdministration.psd1"
if (!(Test-Path $IISModulePath)) {
    Write-Error "IIS Administration PowerShell module not found at $IISModulePath"
    exit 1
}

Import-Module $IISModulePath

# 确保应用池存在
if (!(Get-ChildItem IIS:\AppPools | Where-Object { $_.Name -eq $remote_windows_web_app_pool })) {
    Write-Error "Application Pool '$remote_windows_web_app_pool' does not exist."
    exit 1
}

# 确保站点存在
$sitePath = "IIS:\Sites\$remote_site_name"
if (!(Test-Path $sitePath)) {
    Write-Error "Site '$remote_site_name' does not exist."
    exit 1
}

# 创建应用程序
Write-Host "Creating application '$web_app_name' under site '$remote_site_name' with physical path '$AppPhysicalPath'"
NEW-WebApplication -Name $web_app_name -Site $remote_site_name -ApplicationPool $remote_windows_web_app_pool -PhysicalPath $AppPhysicalPath -Force

if($LASTEXITCODE -ne 0)
{
    Write-Error "Failed to create the application."
    exit $LASTEXITCODE
}

# 确认操作成功
$appPath = Join-Path $sitePath $web_app_name
if (Test-Path $appPath) {
    Write-Host "Application created successfully at '$appPath'."
} else {
    Write-Error "Failed to create the application."
}

exit 0
posted on 2024-06-21 11:01  终南山人  阅读(23)  评论(0编辑  收藏  举报