Один из наших клиентов использует конвейеры выпуска с кодом PowerShell для развертывания блокнотов блоков данных (dev-tst-uat-prd).
То, как он построен, не совсем практично. Таким образом, у нас есть одно рабочее пространство для нескольких бизнес-проектов и, следовательно, отдельные папки для каждого проекта в рабочем пространстве (проект 1, проект 2, проект 3).
И текущий конвейер CICD просматривает все эти папки, выбирает все вложенные папки или файлы и перемещает их по env.
Основная проблема здесь заключается в следующем сценарии:
Допустим, код для проекта 1 и проекта 2 одобрен, отправлен и теперь код находится в среде UAT. Но что-то произошло, и Бизнес не одобрил запуск проекта 2 в производство, а проект 1 должен быть запущен в производство. Здесь у нас проблема: если я запускаю трубку, весь код идет.
это код
$admin_dir = "/ADMIN/"
$data_dir = "/DATA/"
$data_project1 = "/Project 1/"
$data_project2 = "/Project 2/"
$data_project3 = "/Project 3/"
$nb_folders = @($admin_dir, $data_dir, $data_project1, $data_project3, $data_project3)
foreach ($nb_folder in $nb_folders) {
if ($target_ENV -eq 'd') {
Write-Host "The environment is dev, so we don't change resource names in notebooks"
}
else {
$nb_dir = $build_dir + $nb_folder
Write-Host "Changing variables in notebooks"
$files = gci -File -Path $nb_dir
foreach ($f in $files) {
Write-Output $f.name
for ($i = 0; $i -lt $replace_str.Count; $i++) {
(Get-Content $nb_dir\$f).replace($replace_str[$i].Source, $replace_str[$i].Target) | Set-Content $nb_dir\$f
}
}
if ($target_ENV -eq 'p') {
foreach ($f in $files) {
Write-Output $f.name
for ($i = 0; $i -lt $prd_replace_str.Count; $i++) {
(Get-Content $nb_dir\$f).replace($prd_replace_str[$i].Source, $prd_replace_str[$i].Target) | Set-Content $nb_dir\$f
}
}
}
}
if ($target_ENV -eq 'd') {
Write-Host "The environment is dev, so command for copying scripts from repo will be skipped"
}
else {
Import-DatabricksFolder -BearerToken $DatabricksToken -Region "westeurope" -LocalPath $nb_dir -DatabricksPath $nb_folder
}
}
#-------------------------------
# Cleanup
#-------------------------------
#Remove-Item $nb_dir\*
Код YMAL для этой конкретной задачи:
steps:
- task: PowerShell@2
displayName: 'Deploy notebooks'
inputs:
targetType: filePath
filePath: './$(drop)/Deployment Scripts/Databricks/ads_deploynotebooks.ps1'
arguments: '-build_dir $(drop)/Databricks/notebooks'
Может ли быть решение этой проблемы без дублирования CICD для каждого проекта/пути?
Возможно ли, что если ($target_ENV -eq 'u') env является UAT, то пользователь, запускающий конвейер, вручную определяет значение переменной $nb_folder?
@BrightRan-MSFT определяется в переменных конвейера. У меня есть эта строка в моем файле PowerShell ([string]$target_ENV = "#{ENV}#",), а затем она выбирает фактическую переменную из pipeline variables. Я обновил код YMAL, специфичный для моей задачи, которая выполняет развертывание записных книжек.
В соответствии с вашим сценарием значение переменной конвейера ENV не является статичным (жестким кодом), и его можно вручную указать/выбрать значение, когда пользователь вручную запускает конвейер. Верно? @Зеленого цвета
@BrightRan-MSFT ENV действительно является жестко закодированной переменной, но пользователь не передает ее. Это определено в переменных конвейера. Смотрите изображение imgur.com/a/5H6u0zs
Если значение ENV жестко закодировано и не подлежит изменению в сценарии PowerShell, зачем вам определять, является ли это значение другим? @Зеленого цвета
Файл @BrightRan-MSFT ads_deploynotebooks.ps1, который перемещает файлы из репозитория Devops в каждую выделенную среду, является универсальным. так вот в чем причина. В основном он пытается проверить, для какой среды в данный момент работает конвейер. если разработчик, то в этой задаче нет необходимости.
Как проверить, какая среда конвейера работает в данный момент, и как позволить сценарию изменить значение переменной ENV на текущую среду? Если значение env обнаружено при запуске конвейера, пользователь не сможет вручную указать значение переменной на основе значения env. @Зеленого цвета
Требуется ли пользователю вручную указывать значение u только тогда, когда значение env равно «$nb_folder»? Для других значений env будут использоваться значения по умолчанию $nb_folder, установленные в скрипте? @Зеленого цвета
к вам первый вопрос: у меня есть задачи конвейера для каждого окружения (imgur.com/a/OffbZLM), при запуске конвейера есть задача «установить переменные», которые предопределены. как только они определены (один из них — ENV), я могу использовать их в своем скрипте PowerShell ads_deploynotebooks.ps1. Итак, если я перейду от версии EMEA_DEV к версии EMEA_TST, мои переменные изменятся в соответствии с окружающей средой.
@BrightRan-MSFT на ваш второй вопрос: да, это то, что я хочу (одно исправление не u, а p для производства. поэтому, когда в этом случае производство запущено if ($target_ENV -eq 'p'), мой $nb_folder должен быть передан вручную пользователем, который запускает конвейер
@BrightRan-MSFT Один из возможных способов управлять тем, что я хочу, может произойти, если пользователь, которому нужно запустить конвейер выпуска PROD, прокомментирует переменные проекта в ads_deploynotebooks.ps1 и развернет конвейер. а затем снова раскомментируйте для будущих развертываний, которые необходимо распространить из dev. но я считаю это непрактичным.
Я опубликовал ответ на ваш запрос на основе информации, которую вы прокомментировали выше. Проверьте и попробуйте с ним. @Зеленого цвета





Вы можете попробовать использовать параметр конвейера времени выполнения, чтобы позволить пользователю передавать пользовательское значение в скрипт PowerShell:
($target_ENV -eq 'u').param (
[string] $custom_nb_folder
)
if ($target_ENV -eq 'u')
{
# Directly use the PowerShell parameter $custom_nb_folder in this section.
Write-Host "$custom_nb_folder"
. . .
}
parameters:
- name: custom_nb_folder
type: string
default: '/Project 1/'
steps:
- task: PowerShell@2
displayName: 'Deploy notebooks'
inputs:
targetType: filePath
filePath: './$(drop)/Deployment Scripts/Databricks/ads_deploynotebooks.ps1'
arguments: '-build_dir $(drop)/Databricks/notebooks -custom_nb_folder "${{ parameters.custom_nb_folder }}"'
Таким образом, каждый раз, когда пользователь вручную запускает конвейер, он может указать другое значение, чтобы перезаписать значение по умолчанию, в противном случае будет использоваться значение по умолчанию.
ОБНОВЛЯТЬ:
Если вы хотите предоставить пользователям список всех доступных значений и позволить им выбирать и передавать одно или несколько значений в сценарий PowerShell, вы можете сделать следующее:
param (
[string[]] $custom_nb_folders
)
Write-Host $custom_nb_folders
foreach ($item in $custom_nb_folders)
{
Write-Host "$item"
}
parameters:
- name: custom_nb_folders
displayName: 'Delete un-required and only keep required items:'
type: object
default:
- '/ADMIN/'
- '/DATA/'
- '/Project 1/'
- '/Project 2/'
- '/Project 3/'
steps:
- task: PowerShell@2
displayName: 'Deploy notebooks'
env:
JSON_CONTENT: ${{ convertToJson(parameters.custom_nb_folders) }}
inputs:
pwsh: true
targetType: 'inline'
script: |
Out-File -FilePath nb_folders.json -InputObject "$env:JSON_CONTENT"
$arr = Get-Content nb_folders.json | ConvertFrom-Json
Remove-Item -Path nb_folders.json
./$(drop)/"Deployment Scripts"/Databricks/ads_deploynotebooks.ps1 -build_dir "$(drop)/Databricks/notebooks" -custom_nb_folders $arr
Таким образом, когда пользователи вручную запускают конвейер, они могут вручную удалять ненужные и сохранять только необходимые элементы из предоставленного списка по умолчанию.
большое спасибо за решение, попробую. один вопрос: возможно ли сделать множественный выбор для custom_nb_folders? скажем, проект 1 и проект 2?
@Greencolor, вы хотите предоставить список доступных значений и позволить пользователю выбрать одно или несколько из них?
действительно, скажем, у меня есть полный список этих $admin_dir = "/ADMIN/" $data_dir = "/DATA/" $data_project1 = "/Project 1/" $data_project2 = "/Project 2/" $data_project3 = "/Project 3/», и пользователь должен выбрать два из них: «Проект 1» и «Проект 2». Таким образом, он будет перебирать эти пути к файлам.
@Greencolor, любые два пункта из списка или нужно выбрать «/Project 1/» и «/Project 2/»?
это может быть комбинация любого
@Greencolor, Хорошо, дай мне попробовать, позже я сообщу тебе обновленную информацию.
@Greencolor, см. ОБНОВЛЕНИЕ в моем ответе выше.
Откуда в вашем скрипте PowerShell находится переменная
$target_ENV? Можете ли вы предоставить подробный YAML-код вашего конвейера?