Заметки консультанта

Шамрай Александр Владимирович

Posts Tagged ‘git’

Восстановление Git репозиториев в Azure DevOps через Rest Api и PowerShell

Posted by Shamrai Alexander на 20 февраля, 2020

Удаление репозиториев Git в Azure DevOps не приводит к их полному удалению из командного проекта. Удаленные репозитории перемещаются в корзину проекта, но пока нет никаких инструментов для работы с ней. Однако можно воспользоваться функциями Rest Api для того, чтобы:

  1. Узнать какие репозитории были удалены
  2. Восстановить нужные репозитории
  3. Очистить корзину окончательно

Для работы с Rest Api воспользуемся PowerShell, который позволяет довольно быстро выполнять вызовы и разбирать их результаты. Перед выполнением запросов необходимо знать имя командного проекта и имя организации, а также необходимо сгенерировать Personal Access Token. Эти параметры нужно будет установить в скриптах ниже.

Перед тем как выполнить восстановление репозитория, нужно убедиться, что он находится в корзине проекта. Для этого можно воспользоваться следующим вызовом: Get Recycle Bin Repositories. Далее в результирующем списке можно выполнить поиск необходимого репозитория. Пример просмотра корзины (скрипт GetRecycleBinRepositories.ps1):

$listDeletedRepo = «https://dev.azure.com/$org/$teamProject/_apis/git/recycleBin/repositories?api-version=5.1-preview.1″

$resultDeletedRepo = Invoke-RestMethod -Uri $listDeletedRepo -Method Get -ContentType «application/json» -Headers @{Authorization=(«Basic {0}» -f $base64AuthInfo)}

foreach ($repo in $resultDeletedRepo.value)

{

    Write-Host «=============================================»

    Write-Host «Id :» $repo.id

    Write-Host «Name:» $repo.name

}

Для восстановления репозитория нужно выполнить следующую команду: Restore Repository From Recycle Bin. В этой функции нужно становить признак deleted в значение false. Пример восстановления репозитория (скрипт RestoreRepositoryFromRecycleBin.ps1):

$restoreRepo = «https://dev.azure.com/$org/$teamProject/_apis/git/recycleBin/repositories/» + $repoId + «?api-version=5.1-preview.1»

$restoreBody = «{deleted:false}»

$resultrestoredRepo = Invoke-RestMethod -Uri $restoreRepo -Method Patch -ContentType «application/json» -Headers @{Authorization=(«Basic {0}» -f $base64AuthInfo)} -Body $restoreBody

Write-Host $resultrestoredRepo

Если репозиторий не нужен, то его можно удалить окончательно через: Delete Repository From Recycle Bin. При этом здесь нужно передать идентификатор репозитория, который можно узнать через функцию Get Recycle Bin Repositories. Пример удаления репозитория (скрипт для очистки корзины DeleteRepositoriesFromRecycleBin.ps1)

$hardDeleteRepo = «https://dev.azure.com/$org/$teamProject/_apis/git/recycleBin/repositories/» + $repo.id + «?api-version=5.1-preview.1»

Invoke-RestMethod -Uri $hardDeleteRepo -Method Delete -ContentType «application/json» -Headers @{Authorization=(«Basic {0}» -f $base64AuthInfo)}

Write-Host «Deleted repo:» $repo.name

Posted in azure, devops, Microsoft | Отмечено: , , , | Leave a Comment »

Автоматизированное создание GIT запросов на включение кода через сборки Azure DevOps

Posted by Shamrai Alexander на 27 декабря, 2019

Часто командам разработки на основе типовых моделей ветвлений необходимо выполнять рутинные слияния изменений из общего интеграционного потока (master) в свои командные ветви для того, чтобы получить изменения от других команд и понять их влияние на текущую работу. Выполнять это лучше чаще, чтоб раньше узнать о возможных проблемах. Выполнять это можно вручную, что довольно часто игнорируется. А можно этот шаг автоматизировать с помощью вызовов Rest API через PowerShell. При этом достаточно создать один запрос на включение изменений, и он будет периодически пополняться новыми изменениями при каждом новом комите в общий интеграционный поток. Создавать запрос на включение изменений через сборки Azure DevOps можно несколькими путями:

  1. Периодически на основе расписания запуска сборки.
  2. На основе непрерывной интеграции, т.е. каждый новый комит в общий интеграционный поток создает новый запрос на включение изменений в поток разработки команды.

Для создания сборки на основе расписаний необходимо выполнить следующие шаги:

  • Проверить, что пользователь выполнения сборок имеет доступ для создания запросов на изменение через разрешение Contribute to pull requests.

Рисунок 1. Разрешение на работу с запросами на включение изменений

  • Создать новое определение сборки. В моем случае, через классический редактор.

Рисунок 2. Выбор классического редактора

  • Указать репозиторий и ветвь, в которую будут создаваться запросы на включение кода из master.

Рисунок 3. Указание репозитория и ветви

  • Выбрать пустой набор шагов:

Рисунок 4. Определение сборки без шагов

  • Указать, что нет необходимости загружать исходный код. Данный пункт позволяет использовать сервис сборки как обычный планировщик заданий.

Рисунок 5. Отключение скачивания кода

  • Дать возможность заданиям сборки получать ключ доступа к сервису.

Рисунок 6. Разрешение для получения ключа доступа

  • Указать необходимый период выполнения задания.

Рисунок 7. Установка расписания выполнения

  • Добавить только один шаг PowerShell с типом Inline.

Рисунок 8. Задача PowerShell

Сам же скрипт будет выполнять следующие шаги:

  • Зафиксировать необходимые параметры из предопределенных переменных сборки (ключ доступа, адрес организации, имя проекта, имя репозитория и ветви для запроса на включение изменений). Источником изменений будет master.

$token = «$(System.AccessToken)«

$branchTarget = «$(Build.SourceBranch)«

$branchSource = «refs/heads/master»

$branchTragetPath = $branchTarget -replace «refs/heads/», «»

$teamProject = «$(System.TeamProject)«

$repoName = «$(Build.Repository.Name)«

$orgUrl = «$(System.CollectionUri)«

  • Проверка, есть ли новые комиты в мастере через запрос Stats – Get, результат которого содержит свойство behindCount.

$uriBranchStatus = «$orgUrl/$teamProject/_apis/git/repositories/$repoName/stats/branches?name=$branchTragetPath&api-version=5.1″

resultStatus = Invoke-RestMethod -Uri $uriBranchStatus -Method Get -ContentType «application/json» -Headers @{Authorization=(«Basic {0}» -f $base64AuthInfo)}

if ($resultStatus.behindCount -eq 0)

{

    Write-Host «Current branch contains last changes from master»

    Return

}

  • Проверка, существует ли уже активный запрос на включение изменений через метод Pull Requests — Get Pull Requests. Метод возвращает массив соответствующих поисковому запросу запросов на включение кода. Если массив пустой, то и нет запросов на включение кода.

$uriCheckActivePR = «$orgUrl/$teamProject/_apis/git/repositories/$repoName/pullrequests?searchCriteria.targetRefName=$branchTarget&searchCriteria.sourceRefName=$branchSource&api-version=5.1″

$resultActivePR = Invoke-RestMethod -Uri $uriCheckActivePR -Method Get -ContentType «application/json» -Headers @{Authorization=(«Basic {0}» -f $base64AuthInfo)}

if ($resultActivePR.count -gt 0)

{

    Write-Host «PR exists already»

    Return

}

  • Создать запрос на включение изменений через метод Pull Requests – Create, в тело которого передается информация о источнике и цели запроса на включение кода.

$uriCreatePR = «$orgUrl/$teamProject/_apis/git/repositories/$repoName/pullrequests?api-version=5.1″

$bodyCreatePR = «{sourceRefName:’$branchSource‘,targetRefName:’$branchTarget‘,title:’Sync changes from $branchSource‘}»

result = Invoke-RestMethod -Uri $uriCreatePR -Method Post -ContentType «application/json» -Headers @{Authorization=(«Basic {0}» -f $base64AuthInfo)} -Body $bodyCreatePR

Write-Host «Created PR» $result.pullRequestId

Результирующий шаг в сборке:

Рисунок 9. Скрипт в сборке

Содержимое скрипта можно посмотреть здесь: https://github.com/ashamrai/AzureDevOpsExtensions/blob/master/CustomPSTasks/CreatePRBuildTask.ps1

Posted in azure, devops, Microsoft | Отмечено: , , , | Leave a Comment »

Azure DevOps Rest Api. 23. Создание, удаление и восстановление репозиториев GIT

Posted by Shamrai Alexander на 26 августа, 2019

Для взаимодействия с объектами версионного контроля GIT используется клиент GitHttpClient. В рамках данной статьи мы рассмотрим методы:

  • Создание репозитория.
  • Просмотр свойств репозитория
  • Удаление и восстановление репозитория.

Создание репозитория

Создание нового пустого репозитория выполняется довольно просто через метод CreateRepositoryAsync, в который можно передать всего лишь два параметра: объект GitRepository, в котором указать только имя нового репозитория, и название командного проекта. Пример выполнения:

newRepo = new GitRepository();
newRepo.Name = GitNewRepoName;

newRepo = GitClient.CreateRepositoryAsync(newRepo, TeamProjectName).Result;

Также можно создать ответвленный репозиторий через тот же метод. Для этого необходимо свойства родительского репозитория определить через объект GitRepositoryCreateOptions, который мы будем использовать вместо GitRepository. В этом объекте необходимо указать идентификатор родительского репозитория и ссылку на родительский проект. Далее необходимо вызвать метод CreateRepositoryAsync с дополнительным параметром – ссылку на ветвь для ответвления. Пример использования:

GitRepositoryCreateOptions newGitRepository = new GitRepositoryCreateOptions();
newGitRepository.Name = GitNewRepoName;

GitRepository parent = GitClient.GetRepositoryAsync(TeamProjectName, ParentRepo).Result;

newGitRepository.ParentRepository = new GitRepositoryRef();

newGitRepository.ParentRepository.Id = parent.Id;

newGitRepository.ParentRepository.ProjectReference = parent.ProjectReference;

newRepo = GitClient.CreateRepositoryAsync(newGitRepository, TeamProjectName, «refs/heads/master»).Result;

Просмотр свойств репозитория

Получить репозитории можно несколькими методами:

  1. Методом GetRepositoriesAsync, который возвращает список объектов GitRepository. При этом достаточно передать только имя командного проекта в качестве параметра.
  2. Методом GetRepositoryAsync, который возвращает объект GitRepository необходимого репозитория. Здесь можно передать два параметра: имя командного проекта и имя репозитория.

Пример получения репозитория:

GitRepository GitRepo = GitClient.GetRepositoryAsync(TeamProjectName, RepoName).Result; gitThread.Status = Status;
Console.WriteLine(«—————————————————————«);

Console.WriteLine(» GIT REPO: « + GitRepo.Name);

Console.WriteLine(«—————————————————————«);

Console.WriteLine(«Remote url : « + GitRepo.RemoteUrl);

Console.WriteLine(«Size : « + GitRepo.Size);

Объект GitRepository содержит следующие полезные свойства:

  • Id – идентификатор репозитория
  • Name – имя репозитория
  • RemoteUrl – ссылка на репозиторий
  • Size – размер репозитория
  • И другие.

Удаление и восстановление репозитория

Удаление репозитория выполняется с помощью метода DeleteRepositoryAsync, который принимает один параметр: идентификатор репозитория.

Пример удаление репозитория:

GitRepository gitRepo = GitClient.GetRepositoryAsync(TeamProjectName, RepoName).Result;
GitClient.DeleteRepositoryAsync(gitRepo.Id).Wait();

При этом репозиторий переносится в корзину, которая не доступна из обычной панели управления настройками проекта. Чтоб восстановить удаленный репозиторий необходимо:

  1. Получить содержимое корзины командного проекта через функцию GetRecycleBinRepositoriesAsync.
  2. Восстановить репозиторий через функцию RestoreRepositoryFromRecycleBinAsync, которая принимает следующие параметры: объект GitRecycleBinRepositoryDetails с единственным свойством Deleted, имя командного проекта, идентификатор репозитория.

Пример восстановления репозитория

List<GitDeletedRepository> repos = GitClient.GetRecycleBinRepositoriesAsync(TeamProjectName).Result;
if (repos.Count == 0) return;

var repotorestore = repos.FirstOrDefault(x => x.Name == GitRepoName);

if (repotorestore != null)

{

GitClient.RestoreRepositoryFromRecycleBinAsync(new GitRecycleBinRepositoryDetails { Deleted = false }, TeamProjectName, repotorestore.Id).Wait();

Console.WriteLine(«Restored repo: « + GitRepoName);

}

Полностью удалить репозиторий из корзины можно через функцию DeleteRepositoryFromRecycleBinAsync, которая использует в качестве параметров имя командного проекта и идентификатор репозитория.

Пример очистки корзины проекта:

List<GitDeletedRepository> repos = GitClient.GetRecycleBinRepositoriesAsync(TeamProjectName).Result;
foreach (var repo in repos)

GitClient.DeleteRepositoryFromRecycleBinAsync(TeamProjectName, repo.Id).Wait();

Пример тестового приложения можно посмотреть здесь:

https://github.com/ashamrai/TFRestApi/tree/master/23.TFRestApiAppManageGitRepo

Posted in azure, devops, Microsoft | Отмечено: , , | Leave a Comment »

Как синхронизировать GIT репозитории между TFS, VSTS и GitHUB

Posted by Shamrai Alexander на 17 января, 2018

<< Перейти в раздел «Team Foundation Version Control FAQ»

Интересная статья по синхронизации TFS 2015, VSTS и GitHub через сервис сборки: https://blogs.microsoft.co.il/leonj/2017/01/24/synchronizing-tfs-2015-and-vsts-with-github/

Posted in Microsoft, Team Foundation Server FAQ, Version Control FAQ, Visual Studio | Отмечено: , , , | Leave a Comment »

Определение устаревших ветвей в хранилище версионного контроля GIT в VSTS

Posted by Shamrai Alexander на 7 сентября, 2017

Количество создаваемых ветвей в проекте может быть разным. Зависит это от количества участников проекта и декомпозиции на команды, от количества поддерживаемых возможностей разрабатываемого продукта, частоты выпуска и длительности поддержки новых версий. Когда создается много ветвей, рано или поздно встанет вопрос: а нужны ли они все, которые сейчас существуют? Как мне быстро понять, какие ветки «пополнялись» новыми возможностями и исправлениями? В VSTS (а скоро и в TFS) появилась новая возможность – вкладка устаревшие ветви для репозитория GIT, в которой отражаются ветви, не изменявшиеся более 30 дней. Найти это можно здесь:

Posted in Microsoft, Team Foundation Server, Visual Studio, visual studio team services | Отмечено: , , , , | Leave a Comment »

 
%d такие блоггеры, как: