Пользовательский сценарий PowerShell для удержания выпуска в Azure DevOps

Azure DevOps дает вам возможность сохранять информацию о выпуске для анализа. Это также позволяет вам видеть, какие изменения вы внесли в свое приложение с течением времени. Если вам когда-нибудь понадобится вернуться к предыдущей версии, вы можете сделать это с помощью некоторых удобных расширений. Тем не менее, у вас не будет никаких параметров настройки. Таким образом, вам нужно будет прибегнуть к скрипту PowerShell.
Сценарий PowerShell дает вам дополнительные настройки, которые позволяют вам установить политику хранения и выбрать другие этапы. Этот сценарий также вызывает API Azure DevOps и сортирует выпуски по заданным вами параметрам (этап, количество дней с момента последнего выпуска). В этом руководстве я покажу вам, как написать этот скрипт PowerShell. Давайте сначала начнем с первоначальной настройки и того, как установить ваши глобальные переменные.
1. Первоначальная настройка
При первоначальной настройке вам потребуется:
- Добавьте задачу PowerShell и задачу сохранения на неопределенный срок. Вы можете сделать это в своем классическом конвейере в конце группы задач, как показано на рисунке ниже.

- Настройте параметр в задаче сохранения на неопределенный срок, как показано на изображении ниже.

- Задайте свои пользовательские условия для следующего сценария, чтобы заставить его работать с вашей задачей PowerShell:

- Создайте «ShouldRetainForever» в своем сценарии PowerShell. Затем передайте его из задачи PowerShell в задачу сохранения навсегда.

- Запустите сценарий после того, как первоначальная настройка будет готова
Далее давайте посмотрим, как вы можете настроить политику хранения.
2. Сценарий Powershell: политика хранения
Политика хранения будет определяться количеством дней между выпусками, которые вы хотите сохранить, и средами, в которых вы хотите их сохранить. В этом разделе я пошагово пройдусь по сценарию, чтобы помочь вам понять, что делает код.
Глобальные переменные
Когда вы выполняете вызов API к Azure, полезно преобразовать часть вашей информации в переменные, которые вы будете передавать в URI. Таким образом, вы можете легко изменить его и не использовать жестко закодированные значения. Организация и проект будут специфичны для вашей компании. Я также включил две конвейерные переменные. Таким образом, другие, например менеджеры проектов, могут легко изменить политику хранения релизов без жесткого кодирования значений в сценарии.
Примечание. Для переменных конвейера требуется префикс $env: для захвата любых переменных, вводимых из конвейера.
Таким образом, сценарий здесь будет следующим:

Вы можете устанавливать уровень удержания так часто, как хотите, чтобы выпуск сохранялся. В этом случае я установил его на 30 дней. Скажем, приложение выпускается каждую неделю; скрипт проверит, когда был последний сохраненный выпуск. Текущая версия будет сохранена, если она старше 30 дней. Другими словами, если за 30 дней у вас будет 4 релиза, только 1 из 4 сохранится навсегда. После того, как вы установили переменные, давайте напишем функцию, которая будет вызывать API для выполнения поиска, а затем фильтровать данные.
3. Найдите последнюю функцию выпуска
Начнем с написания функции, которая будет вызываться для вызова API. Это большая функция, поэтому я разобью ее для ясности.
- Выделите заголовки. Обратите внимание: если вы хотите получить информацию об окружении (dev, test, stage, production), нам потребуется добавить $expand=environment, чтобы углубиться в API.
- Напишите URI и вставьте наши переменные

- Установите блок try/catch и установите наш ответ равным Invoke-RestMethod @params. Если вызов API завершается сбоем в блоке catch, напишите код состояния и сообщение об ошибке, чтобы проинформировать пользователя и занести в журнал.
Теперь давайте отфильтруем данные.
Данные фильтра
Мы хотим отфильтровать ответ API до данных, с которыми мы хотим работать. Это потому, что первоначальный вызов вернет каждый выпуск для каждого приложения в этом проекте, которых может быть тысячи. Мы берем наш ответ $ и отфильтровываем все данные о выпуске, где среда равна «тест», выпуск прошел успешно, а параметру «сохранено навсегда» присвоено значение «истина». См. приведенный ниже блок кода о том, как это настроить.

Теперь мы отфильтровали все выпуски, выбрав только те, которые соответствуют этому критерию. На этом функция find-lastRelease завершает работу. Далее мы обработаем входные данные из переменных конвейера и посчитаем политику хранения.
- Обработка переменных конвейера
В разделе переменных у нас есть две переменные, которые вы можете установить из конвейера. Мы также хотим убедиться, что если ввод существует, введенные значения переопределяют жестко заданные в скрипте. Если введенных значений не существует, сценарий будет использовать жестко заданные значения.

В приведенном выше блоке кода мы сначала обрабатываем Retention Rate или количество дней. Таким образом, мы говорим, что если переменная конвейера не равна нулю, установите $RetentionRate на то, что установлено в конвейере, и запишите в журнал, что введенное значение присутствовало. Затем мы делаем то же самое для $stageToRetain. Может быть, кто-то хочет оставить релизы на стадии или в разработке, чтобы отслеживать изменения с течением времени. Далее мы устанавливаем нашу политику хранения.
4. Политика хранения
Наша политика хранения — это простое уравнение, которое вы можете установить на любое время или количество дней, в течение которых вы хотите растянуть хранение выпусков. В приведенном ниже фрагменте кода мы устанавливаем для нашей $RetentionPolicy командлет (get-date), который получает текущую дату. Затем мы добавляем к нему дни и вычитаем наш показатель $RetentionRate, который мы установили равным 30. Допустим, сегодня 30 ноября. Мы получаем дату, а затем превращаем ее в только дни (когда вы получаете дату, она дает вам число, месяц, год и время). Затем вычтите 30, чтобы получить дату 31 октября.

Мы обработали переменные конвейера и создали политику хранения. Теперь давайте обработаем условия того, когда что делать.
- Условные операторы
В этом разделе я рассмотрю 3 основных условных оператора. Первый легкий. Если среда выпуска является рабочей, несмотря ни на что, сохраните ее навсегда. Это сохраняет исходную функциональность нашего расширения.

Следующее условие немного сложное, так как оно имеет обратный вызов функции, которую мы написали в начале. Таким образом, если $currentReleaseEnv равно $stageToRetain (в данном случае test), мы обратимся к нашей функции, чтобы вызвать API, найти информацию о выпуске и установить для нее значение $LastRetainedRelease.
Наконец, мы берем $LastRetainedRelease и говорим, что если раньше не было сохранено ни одного, сохраните текущий. В противном случае мы используем политику хранения выпуска, чтобы проверить даты и либо сохранить их, либо нет.

Теперь остался только один шаг. Нам нужно установить нашу логическую переменную и передать ее задаче сохранения, чтобы она работала. Кроме того, нам нужно добавить в наши журналы и сообщения.
- Окончательная регистрация и логическое создание
В последнем блоке кода мы занимаемся ведением журнала и распечаткой значений переменных для отладки. Тем не менее, наиболее важным является создание логического значения, которое активирует задачу сохранения навсегда. Я написал это в начале этой статьи. Тем не менее, я повторю это здесь:
Write-Host «##vso[task.setvariable variable=ShouldRetainForever]$RetainForever»
Если $Retainforever равно true, он передаст ShouldRetainForever следующей задаче и активирует ее. Если $RetainForever равно false, ShouldRetainForever не будет передан, и задача сохранения будет пропущена.

Теперь давайте завершим кратким подведением итогов.
Заключительные слова
Сортировка и сохранение выпусков на стадиях, отличных от рабочей, помогает находить проблемы или отслеживать прогресс приложения с течением времени без необходимости анализировать каждый выпуск. Этот сценарий берет существующую задачу и позволяет ее дополнительно настраивать, чего не хватало в сценарии сохранения на неопределенный срок. Сценарий PowerShell работает довольно хорошо, но я столкнулся с ошибками. Иногда переменные по умолчанию для $stageToRetain и $RetentionRate путаются, если отсутствуют переменные конвейера. Я не уверен, почему это происходит, поскольку значения по умолчанию должны работать, если нет переменных конвейера. Тем не менее, чтобы исправить это, просто добавьте переменные конвейера.
Хотите узнать больше или задать дополнительные вопросы? Ознакомьтесь с часто задаваемыми вопросами и ресурсами ниже.
Часто задаваемые вопросы
Что лучше: встроенные скрипты или скрипты из репозитория?
В Azure DevOps вы можете поместить код в задачу как встроенный код, если вы используете классический конвейер. Это нормально, если сценарий состоит из нескольких коротких строк. Тем не менее, если это сложно, как в учебнике выше, лучше всего сохранить его в репозитории сценариев DevOps и извлечь оттуда.
Почему PowerShell имеет синтаксические несоответствия для групп задач?
Это хороший вопрос. PowerShell имеет собственный синтаксис. Тем не менее, всякий раз, когда вам нужно установить пользовательское условие для задачи, синтаксис отличается от PowerShell. Это может привести к сильному стуку клавиатуры. Пока это не будет исправлено, лучший совет — сохранить несколько примеров в своем блокноте.
Как переменные конвейера используются в PowerShell?
Если вы хотите получить какие-либо переменные из конвейера, вам нужно установить префикс $env:NAME_OF_VARIABLE. Это правильный синтаксис для доступа к значениям переменных конвейера.
Как мне использовать переменные данных ответа?
Когда у вас есть данные, возвращаемые в ответ, вы хотите использовать эти данные, как мы это делали в руководстве. Вам нужно добавить $_. к переменной данных, которую вы хотите использовать. Например, $_.environments. Точка подчеркивания является частью синтаксиса PowerShell, который позволяет программе получать доступ к данным, возвращаемым в ответе JSON.
Каков наилучший способ отладки?
Я рекомендую использовать Visual Studio Code для написания кода, а затем использовать отладчик для запуска сценария. Это удобно при вызове API, поскольку вы можете ввести ответ, проанализировать данные вручную и найти то, что ищете. Тем не менее, как только вы перейдете к конвейеру, вам потребуется больше отладки. Таким образом, будьте готовы потратить большую часть своего времени на отладку, как только вы заработаете локально.
Ресурсы
TechGenix: Учебник по скрипту PowerShell для обновлений после развертывания
Узнайте, как написать скрипт для обновления AppDynamics с помощью PowerShell.
TechGenix: руководство по настройке Azure DevOps для сине-зеленых развертываний
Узнайте, как благодаря Blue/Green Deployment ночи релизов останутся в прошлом.
TechGenix: статья о Azure DevOps и IaC
Узнайте, как Azure DevOps включает инфраструктуру как код.
TechGenix: статья об интерактивных командлетах на основе PowerShell
Узнайте, почему онлайн-командлеты Exchange часто терпят неудачу.
TechGenix: Статья о предотвращении злонамеренного использования PowerShell
Узнайте, как защитить себя от вредоносных объектов с помощью PowerShell.