Конвейеры Azure CICD

Один из наших клиентов использует конвейеры выпуска с кодом 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?

Откуда в вашем скрипте PowerShell находится переменная $target_ENV? Можете ли вы предоставить подробный YAML-код вашего конвейера?

Bright Ran-MSFT 20.06.2024 11:57

@BrightRan-MSFT определяется в переменных конвейера. У меня есть эта строка в моем файле PowerShell ([string]$target_ENV = "#{ENV}#",), а затем она выбирает фактическую переменную из pipeline variables. Я обновил код YMAL, специфичный для моей задачи, которая выполняет развертывание записных книжек.

Greencolor 20.06.2024 12:04

В соответствии с вашим сценарием значение переменной конвейера ENV не является статичным (жестким кодом), и его можно вручную указать/выбрать значение, когда пользователь вручную запускает конвейер. Верно? @Зеленого цвета

Bright Ran-MSFT 20.06.2024 12:34

@BrightRan-MSFT ENV действительно является жестко закодированной переменной, но пользователь не передает ее. Это определено в переменных конвейера. Смотрите изображение imgur.com/a/5H6u0zs

Greencolor 20.06.2024 13:23

Если значение ENV жестко закодировано и не подлежит изменению в сценарии PowerShell, зачем вам определять, является ли это значение другим? @Зеленого цвета

Bright Ran-MSFT 20.06.2024 14:08

Файл @BrightRan-MSFT ads_deploynotebooks.ps1, который перемещает файлы из репозитория Devops в каждую выделенную среду, является универсальным. так вот в чем причина. В основном он пытается проверить, для какой среды в данный момент работает конвейер. если разработчик, то в этой задаче нет необходимости.

Greencolor 20.06.2024 14:13

Как проверить, какая среда конвейера работает в данный момент, и как позволить сценарию изменить значение переменной ENV на текущую среду? Если значение env обнаружено при запуске конвейера, пользователь не сможет вручную указать значение переменной на основе значения env. @Зеленого цвета

Bright Ran-MSFT 20.06.2024 14:22

Требуется ли пользователю вручную указывать значение u только тогда, когда значение env равно «$nb_folder»? Для других значений env будут использоваться значения по умолчанию $nb_folder, установленные в скрипте? @Зеленого цвета

Bright Ran-MSFT 20.06.2024 14:27

к вам первый вопрос: у меня есть задачи конвейера для каждого окружения (imgur.com/a/OffbZLM), при запуске конвейера есть задача «установить переменные», которые предопределены. как только они определены (один из них — ENV), я могу использовать их в своем скрипте PowerShell ads_deploynotebooks.ps1. Итак, если я перейду от версии EMEA_DEV к версии EMEA_TST, мои переменные изменятся в соответствии с окружающей средой.

Greencolor 20.06.2024 14:35

@BrightRan-MSFT на ваш второй вопрос: да, это то, что я хочу (одно исправление не u, а p для производства. поэтому, когда в этом случае производство запущено if ($target_ENV -eq 'p'), мой $nb_folder должен быть передан вручную пользователем, который запускает конвейер

Greencolor 20.06.2024 14:37

@BrightRan-MSFT Один из возможных способов управлять тем, что я хочу, может произойти, если пользователь, которому нужно запустить конвейер выпуска PROD, прокомментирует переменные проекта в ads_deploynotebooks.ps1 и развернет конвейер. а затем снова раскомментируйте для будущих развертываний, которые необходимо распространить из dev. но я считаю это непрактичным.

Greencolor 20.06.2024 15:07

Я опубликовал ответ на ваш запрос на основе информации, которую вы прокомментировали выше. Проверьте и попробуйте с ним. @Зеленого цвета

Bright Ran-MSFT 20.06.2024 15:53
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
12
81
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете попробовать использовать параметр конвейера времени выполнения, чтобы позволить пользователю передавать пользовательское значение в скрипт PowerShell:

  1. В сценарии PowerShell определите параметр 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"
  . . .
}
  1. В YAML-файле конвейера задайте параметр времени выполнения конвейера и передайте его значение параметру PowerShell, определенному в сценарии PowerShell.
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, вы можете сделать следующее:

  1. В сценарии PowerShell определите параметр типа массива, чтобы получать несколько значений, передаваемых в сценарий.
param (
    [string[]] $custom_nb_folders
)

Write-Host $custom_nb_folders

foreach ($item in $custom_nb_folders)
{
    Write-Host "$item"
}
  1. В конвейере YAML определите параметр типа объекта, чтобы предоставить список всех доступных значений.
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 20.06.2024 15:51

@Greencolor, вы хотите предоставить список доступных значений и позволить пользователю выбрать одно или несколько из них?

Bright Ran-MSFT 20.06.2024 15:55

действительно, скажем, у меня есть полный список этих $admin_dir = "/ADMIN/" $data_dir = "/DATA/" $data_project1 = "/Project 1/" $data_project2 = "/Project 2/" $data_project3 = "/Project 3/», и пользователь должен выбрать два из них: «Проект 1» и «Проект 2». Таким образом, он будет перебирать эти пути к файлам.

Greencolor 20.06.2024 15:57

@Greencolor, любые два пункта из списка или нужно выбрать «/Project 1/» и «/Project 2/»?

Bright Ran-MSFT 20.06.2024 16:10

это может быть комбинация любого

Greencolor 20.06.2024 16:13

@Greencolor, Хорошо, дай мне попробовать, позже я сообщу тебе обновленную информацию.

Bright Ran-MSFT 20.06.2024 16:31

@Greencolor, см. ОБНОВЛЕНИЕ в моем ответе выше.

Bright Ran-MSFT 21.06.2024 11:04

Другие вопросы по теме