Обеспечение соблюдения стандартов кода в git до принятия коммита

Хорошо, вот сценарий: группа разработчиков хочет убедиться, что весь новый код соответствует определенным стандартам кодирования и все модульные тесты проходят до принятия фиксации. Уловка заключается в том, что все тесты необходимо запускать на выделенной тестовой машине, и у нас нет доступа для изменения сервера git, поэтому это нужно делать с помощью локального хука фиксации на каждой машине разработчика.

Хотя спецификации довольно строгие (например, мы не переключаемся на Windows или Subversion), это реальная проблема, поэтому есть некоторая гибкость, если у вас есть решение, которое почти подходит.

  • Мы используем Git и * nix.
  • Обновленный код необходимо отправить на другой сервер для запуска набора тестов.
  • Необходимо предоставить список измененных файлов, чтобы убедиться, что они соответствуют стандарту кодирования.
  • Это довольно большая кодовая база, поэтому мы должны отправлять наименьшее количество информации, необходимое для обеспечения идентичных копий кодовой базы.
  • Если тесты не пройдут, необходимо отобразить сообщение с ошибкой и заблокировать фиксацию.
  • Предположим, мы доверяем нашей команде разработчиков и разрешаем обход тестов с опцией --no-verify.

Вопрос: как лучше всего синхронизировать тестовый сервер с локальной средой для выполнения тестов? Какое-то соответствие хэша-хешу с патчем git для нового коммита? Полностью пропустить Git и просто выполнить rsync? Что-то еще?

Обновление от 07.08.13: Я прострелил себе ногу, даже упомянув удаленное репо. Дело не в том, чтобы заблокировать отправку кода в общее / удаленное репо, а в том, чтобы предотвратить даже локальную фиксацию. Будет ли это считаться лучшей практикой, на самом деле не имеет значения в данном случае, поскольку это характерно для небольшой группы разработчиков, которым всем нужна именно эта функциональность. Вопрос в том, как лучше всего достичь цели.


person Jake A. Smith    schedule 31.07.2013    source источник
comment
Разве это не то, для чего нужны запросы на вытягивание? (Конечно, возможно, вы не используете GitHub в этом проекте, но почти наверняка сможете сделать что-то подобное.)   -  person Ajedi32    schedule 31.07.2013
comment
Да, запросы на вытягивание предназначены для проверки кода, но идея здесь в том, что код не следует даже фиксировать в репозитории, если он не пройдет первую автоматическую проверку.   -  person Jake A. Smith    schedule 01.08.2013
comment
Многие проекты Github также используют сервер непрерывной интеграции, такой как Travis, для запуска тестов кода в запросах на вытягивание и отчета о результатах - так что это не только для обзоров кода. Кроме того, код в запросах на вытягивание технически не находится в репозитории до тех пор, пока запрос на вытягивание не будет объединен. Вот почему это называется запросом pull.   -  person Ajedi32    schedule 01.08.2013
comment
у нас нет доступа для изменения сервера git, поэтому это нужно делать с помощью локального хука фиксации на каждой машине разработчика. Или вы можете настроить промежуточный сервер, который отправляется в основное репо после проверки фиксации.   -  person Ajedi32    schedule 01.08.2013
comment
Я понимаю, что вы говорите о запросе на перенос, но речь идет не столько о блокировке репо, сколько о предоставлении разработчикам немедленной обратной связи в рамках их обычного рабочего процесса без необходимости обращаться к внешнему инструменту, например Travis / Jenkins, или ждать электронное письмо, чтобы появиться. Мне нравится идея промежуточного репо. Мне это не пришло в голову.   -  person Jake A. Smith    schedule 01.08.2013
comment
Предположим, мы доверяем нашей команде разработчиков ... Вы им доверяете или вам нужно проверять каждую их фиксацию на предмет нарушений стиля? Похоже, вы ищете техническое решение социальной проблемы (которая может даже не существовать).   -  person Daniel    schedule 09.08.2013
comment
Это не произвольный набор правил, навязываемый группе разработчиков. Это небольшая команда разработчиков, которые вместе решили, что это будет невероятно полезным инструментом для них всех в конкретном проекте.   -  person Jake A. Smith    schedule 09.08.2013
comment
Было бы чрезвычайно полезно знать, какие тесты. Вы говорите о получении «немедленной обратной связи», но для копирования файлов на удаленный сервер и выполнения неизвестного набора тестов потребуется время.   -  person onionjake    schedule 13.09.2013


Ответы (6)


Добавьте настраиваемую команду git, которая:

  1. Временно делает фиксацию
  2. Отправляет его на удаленный сервер
  3. Запускает тесты (используя CI-сервер, post-receive hook или ssh)
  4. Отменяет фиксацию, если тесты терпят неудачу

Создайте исполняемый файл с именем git-test-n-commit и поместите его на свой путь:

#!/bin/bash
echo "Committing results..."
git commit "$@"
echo "Pushing to remote testing server..."
git push remote-server-git-url remote-branch -f
echo "Running tests"
ssh remote-server 'cd my_repo; run-my-tests' || 
   (echo "Tests failed, undoing commit" && git reset HEAD^)

Тогда вместо вызова git commit ARGS разработчики могут вызвать git test-n-commit ARGS. Если тесты пройдут успешно, код останется зафиксированным. Если тесты не пройдут, это будет так, как будто это никогда не было зафиксировано.

person onionjake    schedule 13.09.2013
comment
Хорошее решение! Спасибо. - person Jake A. Smith; 21.11.2013

Short answer:

НЕ


Длинный ответ:

Невозможность выполнить фиксацию из-за каких-то странных локальных хуков кажется мне странной: вы должны отделить фиксацию (т.е. сохранение ваших изменений) от публикации этой фиксации.

Хотя совершенно разумно иметь pre-receive хук на сервере git, о котором вы говорите, который обеспечивает соблюдение ваших правил, это будет драматично для репозиториев ваших разработчиков: каждый раз, когда они хотят сохранить свою работу, попробовать что-то новое или что-то еще, они сначала должны отполировать свой код, прежде чем они смогут выполнить фиксацию.

Это было бы контрпродуктивно: люди чувствовали бы себя как в старые плохие времена, когда им приходилось что-то фиксировать в репо, и каждый мог видеть их ошибки, плохой стиль кодирования и так далее. Вы потеряете свободу, которую дает вам DVCS: дешевое ветвление, локальная история при сохранении центрального репо для производственного кода.

Не применяйте никаких принудительных мер при выполнении локального коммита.

person eckes    schedule 06.08.2013
comment
То, что вы говорите, абсолютно верно почти во всех случаях. Однако это небольшая команда, работающая над частным проектом с высокими стандартами, и как группа они решили, что это именно тот путь, которым они хотят идти. Вопрос не в лучших практиках, а в том, как лучше всего достичь цели для конкретной команды. - person Jake A. Smith; 07.08.2013

Локальные перехватчики фиксации определенно не то, что вам нужно.

Ваше требование о том, что «у нас нет доступа для изменения сервера git, поэтому это должно быть сделано с использованием локального перехватчика фиксации на каждой машине разработчика», является полностью подделкой. Вы всегда можете настроить другой репозиторий, который будет вашим «тестовым пультом», над которым у вас есть полный контроль (который затем будет синхронизироваться с сервером git, который вы не контролируете).

Настроив этот тестовый пульт, вы можете добавить хуки для запуска тестов при любом нажатии. Попытки набрать git push test-remote my-branch для получения результатов тестирования минимальны.

Непрерывная интеграция с Git

Также посмотрите Jenkins, gitlab и т. Д.


Обновление после 07.08.13:

Итак, вы действительно хотите провести некоторые «тесты» на удаленном сервере, чтобы предотвратить коммиты. Если вы хотите предотвратить, основываясь на содержимом самого коммита, используйте ловушку pre-commit. См. этот вопрос, чтобы узнать, как получить список измененных файлов. Один раз. у вас есть эти измененные файлы, вы можете передать их на удаленный сервер с помощью scp или rsync и запустить тестовую команду с ssh.

Если вам нужно проверить сообщение фиксации, используйте ловушку commit-msg.

Вот хороший учебник по хукам: http://git-scm.com/book/en/Customizing-Git-Git-Hooks

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

Они часто используются для обеспечения соблюдения определенных политик, хотя важно отметить, что эти скрипты не передаются во время клонирования. Вы можете принудительно применить политику на стороне сервера, чтобы отклонять отправку коммитов, которые не соответствуют какой-либо политике, но использование этих скриптов на стороне клиента полностью зависит от разработчика. Итак, это сценарии в помощь разработчикам, и они должны быть настроены и поддерживаться ими, хотя они могут быть переопределены или изменены ими в любое время.

person onionjake    schedule 03.08.2013

Я думаю, что лучший подход, который я видел, - это git + gerrit + jenkins. Gerrit вводит понятие набора изменений. Плагин jenkins gerrit может создавать каждый опубликованный набор изменений (запускать любые тесты, которые вы хотите) и отмечать их как «проверенные», после чего проверенный набор изменений можно объединить в основную ветку. Если сборка набора изменений не удалась, коммиттер получает уведомление по электронной почте, после чего он может изменить фиксацию и обновить набор изменений.

person kan    schedule 08.08.2013

После настройки промежуточного сервера, как предлагали другие, установите pre-receive соединение для запуска сценария над входящей фиксацией и нормализации его в соответствии с вашими стандартами кодирования. Часто стандарты кодирования определяются компьютерными правилами. Не заставляйте своих разработчиков постоянно настраивать пробелы, когда простой сценарий bash или что-то еще может сделать это за них. И если у вас есть сценарий для этого, зачем заставлять разработчика запускать его вручную, если он может запускаться автоматически на каждом push промежуточном репозитории.

person Nicholas Shanks    schedule 06.08.2013

Напишите Makefile, который:

  1. Копирует текущие файлы на тестовый сервер.

  2. Находит результат модульных тестов.

2.1. Если аномалий нет, запустите git commit.

2.2 Если есть аномалии, повторите ошибку.

Использование Makefiles для компиляции и коммитов было настоящей находкой. Я могу автоматизировать сложное форматирование и очистку файлов перед фиксацией.

Редактировать:

Конечно, Makefiles - не единственное, что вы можете делать. Ant / Bash / другие языки сценариев могут сделать это за вас.

person SWPhantom    schedule 08.08.2013