Как безопасно и автоматически обновлять зависимости с помощью GitHub Actions и Renovate
В разработке программного обеспечения критически важно следить за обновлениями технологий. Это верно как для разработчиков, которые учатся и обновляют свои навыки, так и для проектов, над которыми они работают и поддерживают.
Когда вы запускаете проект, вы обычно устанавливаете его с использованием последних стабильных версий всех библиотек и инструментов.
Время идет, проект разрастается, добавляются новые функции и библиотеки. Но версии библиотек и пакетов остаются прежними, команда никогда их не обновляет.
В конце концов, зачем вам их обновлять, если проект отлично работает с текущими версиями?
Почему нужно обновлять проекты
Вот несколько причин, по которым вам следует обновлять свои зависимости:
- Решение проблем в старых версиях.
- Добавление исправлений уязвимостей.
- Повышение общей производительности.
- Добавление новых функций.
- ...
Когда вы обновляете свои зависимости, вы решаете проблемы старых версий и улучшаете производительность с помощью новых оптимизаций. Вы также можете использовать новые функции, добавленные другими разработчиками.
Все эти улучшения способствуют поддержанию кода и общей работоспособности проекта.
Все мы работали над проектами, в которых зависимости никогда (или редко) обновлялись. И это совсем не весело.
Так как же нам поддерживать наши проекты в актуальном состоянии?
Прежде всего, вы можете запустить npm outdated
, чтобы увидеть последние выпуски пакетов, которые вы сейчас используете.
Затем вы можете запустить npm update
, чтобы обновить их (он не обновит их до основных версий). Но как узнать, какие обновления сломают проект, а какие нет?
Затем вы должны подумать, когда вам следует все обновить. Когда нужно проверять обновления - каждый день? каждую неделю? ...месяц?
Что вы узнаете в этом руководстве
Вот почему я сделал этот проект: чтобы узнать о GitHub Actions и использовать его, чтобы иметь безопасный способ автоматического обновления зависимостей без сбоя проекта.
В этом руководстве вы узнаете, как использовать приложение Renovate для проверки обновлений зависимостей, а затем отправлять запросы на извлечение для их обновления. Это позволит вам отвлечься от проверки обновлений и сосредоточиться на более важных вещах.
Смысл использования GitHub Actions - настроить рабочий процесс и запускать его с каждым запросом на слияние. Он проверит, что сборка и тесты проходят с обновленными зависимостями, прежде чем добавлять их в проект.
Приступим
Хотя этот подход можно применить к любому проекту, мы будем использовать проект React, созданный с помощью приложения Create React App. Это даст нам базовый проект, в котором все готово для работы.
Если вы хотите проверить окончательный результат перед тем, как начать, вот он:
Contribute to reymon359/github-actions-and-renovate development by creating an account on GitHub.
Итак, начнем с запуска
npx create-react-app my-app
cd my-app
npm start
Если вы используете npm 5.1 или более раннюю версию, вы не можете использовать npx
. Вместо этого установите create-react-app
глобально:
npm install -g create-react-app
А затем запустите:
create-react-app my-app
Настройка рабочего процесса Github Actions
Теперь мы перейдем к определению рабочего процесса GitHub Actions в нашем репозитории для автоматизации процесса.
GitHub Actions - это функция Github, которая помогает автоматизировать рабочие процессы разработки программного обеспечения. Он может обрабатывать все, от простых задач до настраиваемых возможностей сквозной непрерывной интеграции (CI) и непрерывного развертывания (CD) в ваших репозиториях.
В нашей корневой папке мы создадим новую папку и назовем ее .github
. Внутри мы создадим папку workflows
. Вот как ваш проект должен выглядеть после этих шагов:
📁 my-app
├── 📁 .github
│ └── 📁 workflows
├── ...
...
Здесь мы будем создавать и добавлять наши рабочие процессы. Рабочие процессы Github Actions - это автоматизированные процессы непрерывной интеграции, которые мы хотим запустить в нашем проекте.
Рабочие процессы состоят из заданий, содержащих набор шагов. Чтобы объяснить их более наглядно, давайте создадим собственный рабочий процесс и рассмотрим его шаг за шагом.
В каталоге .github/workflows
добавьте файл main.yml
. Я выбрал это имя для простоты, но вы можете дать ему любое другое имя, например build-test.yml
или continuous-integration-workflow.yml
.
📁 my-app
├── 📁 .github
│ └── 📁 workflows
│ └── 📄 main.yml
├── ...
...
Вот как в итоге будет выглядеть рабочий процесс, если вы просто хотите скопировать его и добавить непосредственно перед объяснением.
name: Build and Test
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
build_and_test:
runs-on: ubuntu-latest
strategy:
matrix:
node: [10, 12]
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Install project
run: npm install
- name: Build the project
run: npm run build --if-present
- name: Run tests
run: npm test
Первым параметром нашего рабочего процесса будет его имя:
name: Build and Test
Второй параметр - это триггер.
Мы можем выбрать, будет ли рабочий процесс запускаться событием, таким как запрос push или pull к определенной ветке, или мы даже можем запланировать cron, чтобы он автоматически запускал его каждый определенный промежуток времени!
В нашем проекте мы хотим запускать его при отправке в основную ветку и когда приложение Renovate отправляет запрос на вытягивание для обновления зависимости:
on:
push:
branches: [master]
pull_request:
branches: [master]
Далее мы определяем задания.
В этом примере будет только одно задание: построить и протестировать проект, а также выбрать виртуальную машину, на которой будет выполняться задание.
jobs:
build_and_test:
runs-on: ubuntu-latest
Теперь идет матрица, в которой мы настроим комбинацию версий и систем, которые мы хотим запустить в нашем рабочем процессе. В нашем случае мы запустим его на Node.js 10 и 12.
strategy:
matrix:
node-version: [10, 12]
Наконец, шаги рабочего процесса. Во-первых, это действие извлечения, которое является стандартным действием, которое вы должны включить в свой рабочий процесс, когда вам нужна копия вашего репозитория для запуска рабочего процесса.
Затем вы можете запускать другие действия и процессы. В нашем приложении мы будем использовать действие setup-node с матрицей, которую мы определили ранее. Затем мы добавим шаги для установки проекта, сборки и запуска тестов.
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Install project
run: npm install
- name: Build the project
run: npm run build --if-present
- name: Run tests
run: npm test
Теперь создайте репозиторий GitHub для проекта, зафиксируйте сделанные локальные изменения и отправьте их в него.
Подсказка: если вы хотите создать его быстрее, перейдите на repo.new или github.new. Вы также можете использовать gist.new для gists!
Как только вы внесете изменения, рабочий процесс запустится. После этого вы сможете увидеть, как все прошло Actions
на вкладке проекта GitHub.
Добавить Renovate
Renovate - это бесплатное настраиваемое приложение с открытым исходным кодом, которое помогает автоматически обновлять зависимости в проектах программного обеспечения, получая запросы на вытягивание.
Он используется такими компаниями-разработчиками программного обеспечения как Google, Mozilla и Uber, и вы можете использовать его на GitHub, Gitlab, Bitbucket, Azure DevOps и Gitea.
Мы добавим бота, который будет отправлять запросы на вытягивание в наш репозиторий при появлении обновлений в зависимостях нашего проекта.
Крутая вещь и весь смысл нашего проекта в том, что мы ранее определили в нашем рабочем процессе запуск тестов с запросами на вытягивание. Поэтому, когда Renovate отправляет его, мы автоматически проверяем, нарушат ли предложенные обновления проект, прежде чем объединить их с основной веткой.
Чтобы добавить Renovate в наш проект, мы должны установить его приложение в репозиторий проекта.
Будьте осторожны при выборе репозитория, в который вы хотите добавить Renovate и выберите тот, который был создан ранее. Если вы допустили ошибку и хотите ее перенастроить, вы можете сделать это во вкладке «Приложения» в личных настройках своей учетной записи.
Через несколько минут вам нужно будет принять и объединить полученный запрос на подключение.
После того, как вы его интегрировали, вам необходимо настроить его, обновив файл renovate.json
в корне проекта. Не забудьте вытащить изменения после слияния запроса на извлечение, чтобы он появился.
Вы можете использовать конфигурацию по умолчанию, в которой Renewate будет отправлять запросы на вытягивание всякий раз, когда находит обновления и ждет, пока вы их объедините:
{
"extends": ["config:base"]
}
Чтобы избежать каких-либо проблем и узнать немного больше об инструменте, мы будем использовать конфигурацию с некоторыми из ее наиболее полезных функций.
Если вы хотите узнать больше о его конфигурации, вот документация.
Это будет наш файл renovate.json
:
{
"extends": [
"config:base"
],
"packageRules": [
{
"updateTypes": [
"minor",
"patch"
],
"automerge": true
}
],
"timezone": "Europe/Madrid",
"schedule": [
"after 10pm every weekday",
"before 5am every weekday",
"every weekend"
]
}
В первой части мы сообщаем обновлению, что наша конфигурация будет расширением конфигурации по умолчанию.
{
"extends": [
"config:base"
],
У нас есть packageRules
. После нескольких месяцев его использования я понял, что проверка запросов на включение (время от времени) и их принятие, если тесты пройдены, - это большая трата времени.
Вот почему для параметра automerge
установлено значение true, поэтому Renovate автоматически объединяет запрос на перенос, если рабочий процесс прошел успешно.
Чтобы немного ограничить свободу Renovate, мы определяем, что он может работать только тогда, когда это обновление minor
или patch
.
Таким образом, если это major
обновление того или иного типа, мы сами будем проверять, следует ли добавлять это обновление или нет.
Здесь вы можете найти дополнительную информацию о типах доступных обновлений.
"packageRules": [
{
"updateTypes": [
"minor",
"patch"
],
"automerge": true
}
],
Наконец, у нас есть расписание. Если вы работаете в одиночку или в команде в определенные часы, было бы неплохо делать обновления, когда вы не работаете, чтобы избежать ненужных отвлекающих факторов.
Мы выбираем наш часовой пояс и добавляем для него индивидуальное расписание. Вы можете найти действительные имена часового пояса здесь.
"timezone": "Europe/Madrid",
"schedule": [
"after 10pm every weekday",
"before 5am every weekday",
"every weekend"
],
В любом случае, если вас не волнует время отправки запросов на вытягивание или люди, которые вносят свой вклад в код, находятся в разных часовых поясах, вы можете удалить эту часть.
После обновления конфигурации мы отправляем изменения в GitHub, чтобы приложение Renovate адаптировалось к новой конфигурации.
Теперь у вас, наконец, есть надежно обновленные зависимости проекта, без необходимости их проверять. Вот итоговый проект после выполнения всех шагов, упомянутых выше.
Помните, что если вы добавили часть расписания, вы не сможете автоматически объединить пул-реквест, пока он не будет соответствовать этой конфигурации.
Вывод
Есть и другие способы автоматического обновления зависимостей. Но если вы используете GitHub для размещения своего кода, вам следует воспользоваться преимуществами и максимально использовать его потрясающие бесплатные функции.
Если вам интересно, что еще вы можете делать и автоматизировать с помощью приложений и действий GitHub, просто взгляните на его Marketplace.