Git для веб-сайтов / пост-получение / разделение тестовых и производственных сайтов

Я использую Git для управления исходным кодом и развертыванием своего веб-сайта, и в настоящее время тестовый и действующий сайты работают на одном компьютере. После этого ресурса http://toroid.org/ams/git-website-howto Изначально я придумал следующий скрипт перехвата post-receive, чтобы различать отправку на мой рабочий сайт и отправку на мой тестовый сайт:

while read ref
do
  #echo "Ref updated:"
  #echo $ref -- would print something like example at top of file
  result=`echo $ref | gawk -F' ' '{ print $3 }'`
  if [ $result != "" ]; then
    echo "Branch found: "
    echo $result
    case $result in
      refs/heads/master )
        git --work-tree=c:/temp/BLAH checkout -f master
        echo "Updated master"
        ;;
      refs/heads/testbranch )
        git --work-tree=c:/temp/BLAH2 checkout -f testbranch
        echo "Updated testbranch"
        ;;
      * )
        echo "No update known for $result"
        ;;
    esac
  fi
done
echo "Post-receive updates complete"

Однако я сомневаюсь, что это на самом деле безопасно :) Я ни в коем случае не эксперт по Git, но я предполагаю, что Git, вероятно, отслеживает текущую извлеченную ветку, и этот подход, вероятно, может запутать ее. до бесконечности.

Итак, несколько вопросов:

  1. Это безопасно?

  2. Было бы лучше, если бы мой базовый репозиторий был репозиторием тестового сайта (с соответствующим рабочим каталогом), а затем этот репозиторий отправлял изменения в новый репозиторий действующего сайта, у которого есть соответствующий рабочий каталог для базы действующего сайта? Это также позволило бы мне перенести производство на другой сервер и сохранить цепочку развертывания нетронутой.

  3. Что-то мне не хватает? Есть ли другой чистый способ различать тестовое и производственное развертывание при использовании Git для управления веб-сайтами?

В качестве дополнительного примечания в свете ответа Ви: есть ли хороший способ сделать это, который обрабатывал бы удаление без особого вмешательства в файловую систему?

Спасибо, -Уолт

PS - Сценарий, который я придумал для нескольких репозиториев (и использую, если я не слышу лучше), выглядит следующим образом:

sitename=`basename \`pwd\``

while read ref
do
  #echo "Ref updated:"
  #echo $ref -- would print something like example at top of file
  result=`echo $ref | gawk -F' ' '{ print $3 }'`
  if [ $result != "" ]; then
    echo "Branch found: "
    echo $result
    case $result in
      refs/heads/master )
        git checkout -q -f master
        if [ $? -eq 0 ]; then
            echo "Test Site checked out properly"
        else
            echo "Failed to checkout test site!"
        fi
        ;;
      refs/heads/live-site )
        git push -q ../Live/$sitename live-site:master
        if [ $? -eq 0 ]; then
            echo "Live Site received updates properly"
        else
            echo "Failed to push updates to Live Site"
        fi
        ;;
      * )
        echo "No update known for $result"
        ;;
    esac
  fi
done
echo "Post-receive updates complete"

И тогда репо в ../Live/$sitename (это "голые" репозитории с рабочими деревьями, добавленными после инициализации) имеет базовый пост-прием:

git checkout -f
if [ $? -eq 0 ]; then
    echo "Live site `basename \`pwd\`` checked out successfully"
else
    echo "Live site failed to checkout"
fi

person Walt W    schedule 02.02.2010    source источник
comment
На данный момент я выбрал №2, он пока кажется довольно чистым, пока я не забываю переключиться обратно на основную ветку в тестовом репозитории после нажатия на live-сайт.   -  person Walt W    schedule 02.02.2010


Ответы (3)


Было бы лучше, если бы мой базовый репозиторий был репозиторием тестового сайта (с соответствующим рабочим каталогом), а затем этот репозиторий отправлял изменения в новый репозиторий действующего сайта, у которого есть соответствующий рабочий каталог для базы действующего сайта? Это также позволило бы мне перенести производство на другой сервер и сохранить цепочку развертывания нетронутой.

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

Обычно у меня есть виртуальная машина для тестирования. Работает очень хорошо, и я могу носить его с собой на ноутбуке во время путешествий.

Использование git для развертывания вашего веб-сайта - очень хорошая идея, многие другие люди это делают (например, Роб Конери). Если у вас все равно есть действующий и тестируемый сайт, у вас должны быть отдельные ветки для них в вашем репозитории, настроенные как ветки удаленного отслеживания в соответствующих репозиториях сервера. Ваш рабочий процесс становится таким же простым, как выполнение работы в своей тестовой ветке, запускать ее для тестирования, тестировать, объединять для работы и запускать в реальном времени.

Честно говоря, не усложняйте себе задачу.

person Johannes Rudolph    schedule 14.02.2010
comment
Это похоже на то, что на прошлой неделе я неплохо отработал. - person Walt W; 15.02.2010

Думаю, что оба способа сработают.

Вы также можете использовать «git archive master | tar -C c: / temp / BLAH -x» и «git archive live-site | ssh live-site 'tar -C / var / www -x'».

Хранение отдельных репозиториев может быть полезным, но «проталкивание внутрь другого связанного с push-уведомлением крючка» выглядит сложным, и я ожидаю, что это будет медленным. Такая длинная цепочка, которая будет медленной и хрупкой.

Может быть, живые обновления сайта надо запускать вручную после тестирования "тестовой" версии?

person Vi.    schedule 05.02.2010
comment
Смола может быть хорошей идеей; Я обязательно посмотрю на это на следующей неделе. Я не совсем уверен, насколько хорошо это будет работать, поскольку я запускаю скрипты через msysGit. Но, похоже, они упакованы смолой, так что может быть. - person Walt W; 06.02.2010
comment
Хорошо - вот вопрос об этом ответе - мне нравится концепция тарринга, но есть одна неудовлетворительная часть - я бы хотел, чтобы обновления были как можно более плавными. Одним из преимуществ трюка с несколькими репозиториями является то, что, хотя и сложно, файловая система изменяется только в соответствии с дельтами каждой фиксации - однако подход tar потребует rm -rf'ing каталога развертывания, ЗАТЕМ извлечение tar. . . Может быть, есть флаг tar, о котором я не знаю? Подход tar хорош по ряду причин, но я думаю, что мой хост опасно удалять все между обновлениями. - person Walt W; 09.02.2010
comment
Тогда вам, вероятно, следует использовать отдельные репозитории. Но я все еще не думаю, что нажатие на какую-то специальную ссылку должно автоматически обновлять производственный сайт. Это просто не должно быть так просто. - person Vi.; 11.02.2010
comment
Обновление сайта с помощью git checkout само по себе не является атомарным. Что произойдет, если какой-то пользователь войдет на сайт только во время оформления заказа? Вы можете извлечь / проверить сайт в какой-либо другой каталог и указать файл конфигурации сайта, чтобы использовать этот другой каталог. - person Vi.; 11.02.2010
comment
Какие файлы хранятся в репозитории? Как несколько небольших взаимосвязанных файлов PHP или больших независимых двоичных объектов? - person Vi.; 11.02.2010
comment
Ви - Я согласен, что это не должно быть так просто, но учтите, что репозиторий, содержащий ветку для отправки на работающий сайт, может быть частным репозиторием - не обязательно общедоступной копией. Что касается других ваших моментов - да, git checkout не атомарен, но его эффекты более ограничены, чем общая команда tar. Что касается файлов, хранящихся в репо, это в основном куча мелочей. - person Walt W; 15.02.2010

Я также следовал тому же руководству на toroid.org, но хотел бы отметить, что, хотя вы начали с чистого репозитория, добавив рабочий каталог, скорее всего, потребуется дополнительная обработка. Я обнаружил, что следующий хук полезен, если у вас есть контент, который может изменяться динамически или иным образом, и вы не хотите терять данные при использовании git checkout -f

предварительно получить

#!/bin/sh
git add -A
git diff --quiet --cached
if [ $? -gt 0 ]; then
    git commit --quiet -m "autocommit"
    echo "Working Directory was out of sync. Pull to receive updated index."
    exit 1
fi

Это остановит push, если в удаленном рабочем каталоге есть изменения. Представьте, что кто-то (веб-сервер) вносит изменения, но забывает их зафиксировать. Использование checkout с -f приведет к отмене этих изменений. Этот хук - хорошее место, чтобы этого не произошло, но было бы неплохо, если бы на удаленном сервере также был хук, вызываемый до извлечения, чтобы вы могли беспрепятственно получать эти изменения.

пост-получение

#!/bin/sh
git checkout -f
echo "Working directory synced."

Что касается двух веток, я подумал, что ваше первое решение было более элегантным, чем необходимость иметь дело с несколькими репозиториями. Если вы действительно хотите изолировать свой производственный сайт, вы можете использовать rsync локально, который имеет аналогичное дельта-исправление. У меня была бы тестовая и стабильная ветка в репозитории с только тестовым сайтом в качестве рабочего каталога. Когда все будет готово к выпуску, объедините тестирование в стабильную ветку, нажмите и получите ловушку, ищущую коммиты в стабильную ветку, и вызовите rsync.

person tcp    schedule 10.04.2010
comment
+1 за предварительный комментарий - это действительно полезный совет, спасибо. Что касается нескольких репозиториев, на самом деле это не так уж и плохо :) Однако rsync определенно является еще одним жизнеспособным вариантом. Спасибо! - person Walt W; 12.04.2010
comment
git add . не улавливает все изменения (удаления), изменен на git add -A - person tcp; 23.04.2010