Недавно Действия GitHub добавили еще один инструмент к рабочим процессам, которые мы все централизовали вокруг GitHub, благодаря чему стало еще проще заставить ботов выполнять сложные для процесса вещи, которые мы, люди, делать не хотим.
Когда я услышал новости, я подумал, как это работает с Travis CI, который мы также используем, а затем я подумал, что автоматизация линтинга с помощью Actions - это первый логический шаг (и сейчас мы используем это, хотя это все еще в разработке!)
Благодаря этому проекту я узнал кое-что о действиях GitHub и, возможно, об идеологии, лежащей в основе того, что GitHub пытается здесь сделать.

Итак, давайте рассмотрим некоторые из моих знаний, и в этой статье мы создадим простое действие GitHub. Мы выполним действие, которое запускается при любой фиксации, и рассмотрим сообщение фиксации.
Как выполняются действия - создание основы для нашего проекта
Первый шаг - и самый простой - это настройка нашего репозитория.
Довольно аккуратно. По сути, каждое действие выполняется в контейнере Docker, которому предоставляется разнообразный контекст из Github (переменные среды, имеющийся репозиторий), который затем может хорошо выполняться ... все, что вы можете в контейнере Docker!
По большому счету, первое, что я узнал из этого процесса, - это то, насколько мне не хватает знаний в отношении написания сценариев bash, но я поделюсь некоторыми интересными приемами и передовыми практиками, которые я нашел в ближайшее время!
Действие разбито так:
+-- Dockerfile +-- README.md +-- your_entry_script.sh +-- ... any additional folders for organization
Dockerfile может быть настолько простым или сложным, насколько вы хотите, но в конечном итоге это место для установки небольших метаданных Action (LABEL и т. Д.), Установки зависимостей и инициализации команды ввода для контейнера. . Вот что использует наш проект сообщений git commit, который вы можете скопировать в качестве отправной точки:
FROM alpine:latest
LABEL "com.github.actions.name"="git-commit-message-check"
LABEL "com.github.actions.description"="Check the quality of the git commit message"
LABEL "com.github.actions.icon"="check-square"
LABEL "com.github.actions.color"="yellow"
RUN apk add --no-cache \
jq \
curl \
git
COPY "run-git-message-check.sh" /usr/bin/run-git-message-check
CMD ["sh", "/usr/bin/run-git-message-check"]
Я думаю, что прелесть GitHub Actions заключается в том, что они, неявно через характер дизайна, поощряют легкие действия, которые делают одно, и делают это хорошо.
Этот образ мышления начинается с корня, с минимального контейнера Docker alpine. Этот контейнер содержит самое необходимое, поэтому необходимо установить любую зависимость, даже такую распространенную, как curl.
Мы устанавливаем еще несколько зависимостей, которые потребуются нашему сценарию (скоро вы увидите!), А затем КОПИРУЕМ наш основной сценарий в контейнер. Обратите внимание, что вам нужно chmod + x свой скрипт локально, чтобы гарантировать, что при копировании он будет исполняемым!
Создание сценария оболочки (и что я узнал о bash)
Теперь вы можете писать на любом языке, который будет работать в контейнере Docker, но было весело попробовать поиграть мои (несуществующие) мускулы bash!
Первое, что нужно знать о действиях, - это то, что при запуске любого скрипта у вас есть изящный дополнительный контекст, с которым можно работать. Действия обеспечивают надежную среду выполнения, предоставляя вам много информации о вашем репозитории, инициированном событии и действующих лицах (системах или людях), стоящих за ним.
Интересный способ вникнуть в это - создать Action, который ничего не делает, а только выводит среду выполнения. Взглянем:
#!/bin/bash
set -e
set -o pipefail
main() {
jq --raw-output . "$GITHUB_EVENT_PATH"
}
main
Добавьте это в свой проект как run-git-message-check.sh. На данный момент, имея только этот код оболочки и контейнер Docker, вы очень близки к добавлению действия. Если вы хотите сделать паузу и попробовать, я рекомендую прочитать документацию GitHub по Создание нового действия GitHub, поскольку в ней подробно описаны детали его развертывания, которых мы не будем рассматривать в этой статье. (В основном потому, что здесь мы сосредоточены на функциональности Action, а все остальное - соединяющие элементы!)
Мне нравится, насколько прост этот сценарий оболочки, и я узнал несколько полезных вещей:
- set -e останавливает выполнение сценария оболочки всякий раз, когда возникает ошибка команды или конвейера. Это сохраняет наши действия достаточно разумными, и это что-то новое для меня в мире bash!
- Так же я много узнал о pipefail! Об этом уже написано отличное письмо, поэтому я рекомендую прочитать его!
- Я узнал о shellcheck, который засоряет ваш bash! В моем примере репо, связанном позже, я предоставляю средства использования этого против кода, который мы пишем.
Кроме того, я ввел этот шелл-код и контейнер Docker в рабочий процесс, и вы можете увидеть фрагмент вывода на вкладке «Действия» GitHub (для краткости вырезано):
### STARTED post git quality control 19:04:00Z
Pulling image: gcr.io/github-actions-images/action-runner:latest
latest: Pulling from github-actions-images/action-runner
cd784148e348: Already exists
1a34a342bc8b: Pulling fs layer
571706cf6933: Pulling fs layer
....
....
(5/10) Installing curl (7.61.1-r1)
(6/10) Installing expat (2.2.5-r0)
(7/10) Installing pcre2 (10.31-r0)
(8/10) Installing git (2.18.1-r0)
(9/10) Installing oniguruma (6.8.2-r0)
(10/10) Installing jq (1.6_rc1-r1)
Executing busybox-1.28.4-r2.trigger
Executing ca-certificates-20171114-r3.trigger
OK: 20 MiB in 23 packages
---> b3a1810ba635
Step 7/8 : COPY "run-git-mesage-check.sh" /usr/bin/run-git-message-check
Красивый! По сути, он создает и запускает контейнер Docker, и весь журнал содержится в этом выводе.
Среда выполнения
Как и выше, мы использовали jq для проверки GITHUB_EVENT_PATH,, который представляет собой полезный файл JSON с такими метаданными, как :
{
"after": "1870aa8285a40ac84debc34885314b0553c1de55",
"base_ref": null,
"before": "b0dba7f5a0b290bfabcf4498ff19980f3c0b7fd6",
"commits": [
{
"added": [],
"author": {
"email": "[email protected]",
"name": "Bartek Ciszkowski",
"username": "bartek"
},
"committer": {
"email": "[email protected]",
"name": "Bartek Ciszkowski",
"username": "bartek"
},
"distinct": true,
"id": "1870aa8285a40ac84debc34885314b0553c1de55",
"message": "Fix COPY command in Docker",
"modified": [
"Dockerfile"
],
"removed": [],
"timestamp": "2019-01-15T21:14:45-05:00",
"tree_id": "a791cf15588173a748df25d3b92208f31d384025",
"url": "https://github.com/bartek/action-git-message/commit/1870aa8285a40ac84debc34885314b0553c1de55"
}
],
...
}
Эти данные были получены, когда наш скрипт запустил команду jq в репозитории, который я создавал для этого проекта. Вы можете увидеть последний коммит (в котором я допустил опечатку в команде COPY). Вышеупомянутое - это лишь крошечный фрагмент метаданных, доступных вам в событии GitHub JSON.
Славно! Столько информации. В нашем проекте мы будем использовать массив коммитов, просматривая каждое сообщение и проверяя, соответствует ли оно нашим лучшим практикам. Да, этот бот немного пассивно-агрессивен, но помните, это всего лишь способ научиться! Ваш настоящий живой бот может быть лучше.
Хорошо, давайте доработаем ядро этого скрипта. Мне понравилась эта статья о лучших методах работы с сообщениями git, и в ней подчеркиваются следующие правила:
- Отделяйте тему от текста пустой строкой
- Ограничьте строку темы до 50 символов
- Используйте заглавные буквы в теме письма
- Не заканчивайте строку темы точкой
- Используйте повелительное наклонение в теме письма
- Оберните тело на 72 символа
- Используйте текст, чтобы объяснить что и почему по сравнению с как
Мой bash-foo прошел здесь серьезное испытание, поэтому я сосредоточился на соблюдении правила 2, добавив при этом возможность публиковать комментарии на GitHub для всех соответствующих ша коммитов. Я попытаюсь скрыть свое отсутствие навыков bash, сказав, что я сохраняю пример простым, чтобы быть кратким, но я уверен, что кто-то придет сюда, прочитает это и предоставит однострочник, чтобы свести мой скрипт к нулю (на самом деле - Я был бы признателен). Без дальнейших церемоний:
#!/bin/bash set -e set -o pipefail URI=https://api.github.com API_VERSION=v3 API_HEADER="Accept: application/vnd.github.${API_VERSION}+json; application/vnd.github.antiope-preview+json" AUTH_HEADER="Authorization: token ${GITHUB_TOKEN}" post_quality_control_message() { for i in ${!COMMIT_IDS[@]}; do id=${COMMIT_IDS[$i]} curl -sSL -H "${AUTH_HEADER}" -H "${API_HEADER}" -d @quality_message.json -H "Content-Type: application/json" -X POST "${URI}/repos/${GITHUB_REPOSITORY}/commits/${id}/comments" done } main() { commits=$(jq --raw-output .commits "$GITHUB_EVENT_PATH") COMMIT_IDS=() for row in $(echo "${commits}" | jq -r '.[] | @base64'); do message="$(echo "$row" | base64 --decode | jq -r '.message')" if [ ${#message} -ge 50 ]; then COMMIT_IDS+="$(echo "$row" | base64 --decode | jq -r '.id')" continue fi done post_quality_control_message; } main
Для справки, весь этот код вы можете найти в моем репозитории.
Здесь происходит несколько вещей, но вкратце:
- В качестве первого шага я использую jq для получения коммитов из данных события Github. Это снова файл JSON, предоставленный средой выполнения GitHub Actions.
- Наше действие запускается всякий раз, когда в репозитории происходит какое-либо событие push (это определяется, когда вы выполняете фактический рабочий процесс), поэтому у нас есть контекст коммита git, среди других деталей в нашей среде.
- Затем я напрягаю свои несуществующие мускулы bash и перебираю каждую фиксацию, которую нашел в JSON, фиксируя длину сообщения, проверяя, превышает ли она 50 символов или больше - и если да, сохраняя этот идентификатор фиксации для последующего отчета. .
- Затем, перебирая все собранные идентификаторы фиксации, я использую GitHub API для отправки сообщения в комментарии к фиксации. Вот как это выглядит:

И с этим у нас есть функциональное действие GitHub.
То, что мы создали сегодня, бесполезно изолированно, но это дало нам некоторое представление о том, что могут делать GitHub Actions! Мы убедились, что получаем прекрасную и компактную среду выполнения, можем запускать множество произвольных команд и взаимодействовать с GitHub API.
Все это собрано вместе, и вы получите довольно мощную экосистему!
Мне очень понравилось проводить время с GitHub Actions, и я в целом восхищен их возможностями. Как для человека, который тратит значительную часть своих умственных способностей на размышления о том, как улучшить процесс и уменьшить препятствия для разработчиков, это дополнение дает больше информации.
Мне нужно еще многому научиться, и я надеюсь, что вы сочли это хорошим началом. Я настоятельно рекомендую вступительный доклад о действиях GitHub, когда они были представлены на AWS re: Create ранее в 2018 году.
Если у вас возникли проблемы с запуском того, что я предоставил в моем репозитории, или вы хотите внести дополнительную информацию, пожалуйста, свяжитесь с нами! Я бы хотел узнать больше.
Следите за нами в Medium и Twitter, чтобы увидеть больше отрывков из мира технологий согласно G!
Хотите помочь G Adventures изменить жизнь людей и путешествовать по миру? Ознакомьтесь со всеми нашими вакансиями и подайте заявку сегодня.