
В прошлом году GitHub без лишнего шума выпустил новую возможность, которую быстро заметили в сообществе пользователей, — файлы README в профилях. По сути, README-файл профиля представляет собой глобальный файл README, связанный с вашим профилем GitHub. Чтобы он появился, нужно создать публичный репозиторий, имя которого совпадает с вашим именем пользователя на GitHub. Например, мое имя пользователя — osteel, поэтому я создал osteel/osteel в качестве такого репозитория.
При добавлении такого репозитория в своем аккаунте вы увидите табличку, подобную этой:

Создав репозиторий, поместите туда файл README и добавьте в него краткую автобиографию с перечислением всех своих достоинств. Тогда страница вашего профиля на GitHub будет по умолчанию отображать содержимое этого файла:

Изящно и просто.
Просматривая примеры в поисках вдохновения, я наткнулся на версию от Саймона Уиллисона (Simon Willison) с динамической загрузкой контента, такого как список недавних работ и публикаций из блога. В своей статье автор поясняет, что для достижения цели он использовал GitHub Actions в связке с Python, а я решил сделать что-то подобное на PHP.
Местозаполнитель
Сперва нужно создать местозаполнитель в файле README — на его месте будет размещаться динамический контент. Мне хотелось автоматически вставлять последние публикации из своего блога, поэтому я использовал следующие теги:
<!-- posts --><!-- /posts -->
Возможно, вам знаком этот формат. Поскольку файлы формата Markdown поддерживают HTML, я использовал HTML-теги комментариев, зная, что они не будут отображаться на странице моего профиля.
Скрипт на PHP
Уже не помню, когда в последний раз писал на PHP без фреймворка, поэтому для создания базового PHP-скрипта мне сначала пришлось найти в сети краткую статью, в которой даны инструкции по работе с зависимостями через менеджер пакетов Composer.
Оказывается, это довольно просто! Первым шагом я инициализировал проект с помощью следующей команды:
$ composer init
Далее я установил легковесную библиотеку для парсинга RSS-ленты моего блога:
$ composer require dg/rss-php
Затем я добавил файл posts.php в корневую папку проекта и написал в нем следующий код:
<?php // Load Composer's autoload require_once __DIR__ . '/vendor/autoload.php'; // Load the RSS feed $feed = Feed::loadRss('https://tech.osteel.me/feeds/rss.xml')->toArray(); // Generate the list of blog posts $posts = ''; foreach (array_slice($feed['item'], 0, 5) as $post) { $date = date('d/m/Y', strtotime($post['pubDate'])); $posts .= sprintf("\n* **[%s]** [%s](%s \"%s\")", $date, $post['title'], $post['link'], $post['title']); } // Generate the new content $content = preg_replace( '#<!-- posts -->.*<!-- /posts -->#s', sprintf('<!-- posts -->%s<!-- /posts -->', $posts), file_get_contents('README.md') ); // Overwrite the file file_put_contents('README.md', $content);
Тут все относительно просто: вверху я добавляю как зависимость созданный в Composer файл автозагрузки autoload, позволяющий мне загружать RSS-парсер и генерировать список публикаций из блога в виде строки в формате Markdown.
Затем текущее содержимое файла README загружается в переменную $content, после чего Markdown-строка вставляется между тегами <!-- posts --> и <!-- /posts --> с помощью функции preg_replace.
Наконец, все содержимое файла заменяется новым при помощи функции file_put_contents.
Действие в GitHub Actions
GitHub Actions — это сравнительно новое дополнение к GitHub, позволяющее разработчикам создавать действия для автоматизации различных задач CI/CD, таких как прогон набора тестов или развертывание веб-сервисов.
Действия определяются в формате YAML и сохраняются как файлы в папке .github/workflows в корне проекта. Определение действия содержит список операций к выполнению.
Вот мой файл действия, который я назвал posts.yml:
name: Update blog posts on: push: workflow_dispatch: schedule: - cron: '0 0 * * *' jobs: build: runs-on: ubuntu-latest steps: - name: Clone repository uses: actions/checkout@v2 - name: Install PHP uses: shivammathur/setup-php@v2 with: php-version: '7.4' - name: Install Composer dependencies run: composer install - name: Insert blog posts run: php posts.php - name: Push changes uses: stefanzweifel/git-auto-commit-action@v4 with: commit_message: Updated latest blog posts
Опять же, относительно простая структура. Сначала присваиваем действию имя, а затем определяем список событий, которые должны его инициировать: отправка какого-нибудь кода в репозиторий, запуск вручную из интерфейса (workflow_dispatch) или периодический запуск подобно cron-заданию (здесь — ежесуточно в полночь).
Затем указываем, что действие будет запускаться на образе Ubuntu и в рамках действия будут выполняться следующие операции:
установить зависимости через Composer;
запустить PHP-скрипт;
сделать коммит и отправить изменения командой push (если таковые имеются).
Вот и все! Теперь мой профиль на GitHub автоматически обновляется каждый раз, когда я публикую новую статью.
Заключение
Этот небольшой эксперимент продвинул нас вперед в освоении возможностей GitHub Actions, которые я планирую использовать все чаще и чаще в будущем. Кроме того, было интересно снова попробовать PHP в качестве простого скриптового языка для написания кода в процедурной парадигме.
Я намеренно опустил несколько моментов, чтобы эта статья была короткой и простой. Детали реализации можно посмотреть в репозитории.
Статья была изначально опубликована на ресурсе tech.osteel.me.
Материал переведен в преддверии старта курса "PHP Developer. Professional".
