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

Соответственно, при обновлении приложения его нужно обновить на всех серверах. Я написал нам утиль, чтобы этот процесс автоматизировать.

Теперь подробнее, что надо делать. Скажем, имеется десять серверов, на каждом размещена копия некоторого приложения. Само-собой, копии идентичны. И каталог каждой представляет собой Git-репозиторий. И ещё есть центральный Git-репозиторий (у нас поднят локальный на отдельном сервере, но можно использовать и https://github.com/), в котором хранятся исходники, а также локальные репозитории на компьютерах разработчиков.

Вот так примерно это можно представить на картинке:

Копии репозитория приложения на серверах

И вот когда настаёт время очередного обновления этого приложения, то нужно на каждом сервере (то есть, 10 раз), забрать из центрального репозитория последний коммит и выкатить его в локальном репозитории. Тут кто-то может сказать, что какая-то не очень у нас система обновлений, и так оно и есть, скорее всего, но проблема уже создана, так что будем с ней бороться.

Для максимального устранения человеческого участия из этого процесса я написал приложение MassUpdateFromGit:

Главное окно приложения обновления Git репозиториев

Приложение работает со сценариями обновления. Однажды созданный сценарий далее можно неоднократно использовать, а также создать ярлык для быстрого его запуска. То есть, от человека потребуется только кликнуть ярлык - приложение запустится с указанным сценарием, и останется только нажать на кнопку старта обновления.

Сценарий обновления представляет из себя XML примерно такого вида:

<?xml version="1.0" encoding="utf-8"?>
<scenario name="proj" lastModified="04.10.2015 19:42:51">
  <gitLink>http://ourserver:8888/some/proj.git</gitLink>
  <gitLocal>D:\www\proj</gitLocal>
  <gitBranch>server/master</gitBranch>
  <paths>
    <path>\\server1\\d$\www\proj\</path>
    <path>\\server2\\d$\www\proj\</path>
    <path>\\server3\\d$\www\proj\</path>
    <path>\\server4\\d$\www\proj\</path>
    <path>\\server5\\d$\www\proj\</path>
    <path>\\server6\\d$\www\proj\</path>
    <path>\\server7\\d$\www\proj\</path>
    <path>\\server8\\d$\www\proj\</path>
    <path>\\server9\\d$\www\proj\</path>
    <path>\\server10\\d$\www\proj\</path>
  </paths>
</scenario>

Как это работает. Например, мы только что закоммитили последние изменения и отправили коммит в центральный репозиторий. Теперь для обновления приложения на всех серверах открываем приложение и:

  1. Указываем ссылку на центральный репозиторий;
  2. Задаём путь до локального репозитория, в котором отправили коммит;
  3. Пишем название ветки, которую нужно выкатить на серверах;
  4. Добавляем пути до локальных репозиториев на серверах.

На этом сценарий готов, его можно сохранить для дальнейшего использования.

По нажатию на кнопку запуска обновления (зелёная такая, в правом нижнем углу), приложение выполнит следующие команды для каждого из добавленный путей:

# получить из центрального репозитория последнюю инфу
git.exe --git-dir="\\server1\d$\www\proj\.git" --work-tree="\\server1\d$\www\proj" fetch --all

# выкатить в репозиторий свежую ветку
git.exe --git-dir="\\server1\d$\www\proj\.git" --work-tree="\\server1\d$\www\proj" reset --hard server/master

Ну и всё.

Загрузить приложение можно здесь:

Для запуска нужна только папка bin\Release, остальное можете удалить. Из самой папки нужны только эти файлы:

  • updateFromGit.exe
  • updateFromGit.exe.config
  • Ookii.Dialogs.Wpf.dll

Можете оставлять замечания/предложения на этой странице либо тут в каментах.