Всем привет!
Пока сессия только начинается, а зачетные недели в самом разгаре я немного раскидался и хочу поделиться с Вами тем, как я выстроил процесс написания курсача. Возможно, такой формат больше подошел бы для написания диплома так как объем курсача все таки не настолько большой, чтобы так делать, однако совсем недавно я делал довольно объемную лабу по одному предмету и сыт по горло версткой формул в ворде.
Курсач я решил писать на латехе. Я не буду описывать то, как я это делаю. Латех - очень крутая штука и всю его крутость, думаю, не описать в одной статье. Может быть когда нибудь я даже это сделаю, но сегодня я хочу рассказать больше о процессе работы над курсачом.
Для тех, кто не в курсе: LaTeX - язык математической верстки, который можно компилировать в PDF файлы. Тыц
В отличие от файлов doc/docx .tex файлы - это код, а не нечитаймый xml или вообще бинарник, поэтому при разработке документов на латехе можно очень легко контролировать версии и даже делать это в команде благодаря системам контроля версий, например, git. И это несомненный плюс, так как позволяет отказаться от чего-то такого:
Окей, git это круто, но этого недостаточно для полного погружения, идем дальше. Курсач я пишу в VS Code и для этой ide есть просто шикарное расширение для работы с latex
Бам - https://marketplace.visualstudio.com/items?itemName=James-Yu.latex-workshop
Там есть поддержка разных компиляторов, очень гибкая настройка, хот-релоад при сохранении, просмотр pdf прямо в ide и много чего еще и это очень круто, советую. Также рекомендую поставить спеллчекер типа
https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker-russian
потому что все мы люди и все ошибаемся.
Так, ну со средой разобрались, использовать будем гит, выгружать будем на гитхаб, все как обычно. Но чего-то все равно не хватает. Хм... Точно! Нам нужен CI/CD.
Что есть CI/CD?
Вкратце, это такой подход к разработке, при котором автоматизируются такие процессы как тестирование, сборка и деплой продукта, позволяя очень быстро выявлять потенциальные проблемы и решать интеграционные проблемы.
Это очень удобно при разработке приложений, но для разработки документов на latex это не менее удобно.
Мы этим и займемся, а так как развернулись на гитхабе, будем использовать Github Actions.
Начинаем!
Для начала, нужно на вкладке Actions создать файлик с указаниями чо делат, этот файлик будет храниться в нашей репе в папке .github/workflows
name: LaTeX ci/cd
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
Мы говорим, что хотим запускать воркфлоу когда произошел пуш или пул влился пул реквест в master (#BLM ëпта) ветку нашей репы. Хорошо, а что делать?
jobs:
build_master:
runs-on: ubuntu-latest
Назовем джобу build_master, потому что она билдит мастер (вау) и прикажем запускаться на ubuntu-latest
Дальше идут шаги нашего воркфлоу и их довольно много для latex документа
steps:
- name: Set up Git repository
uses: actions/checkout@v2
- name: Compile LaTeX document
uses: dante-ev/latex-action@master
with:
root_file: main.tex
- name: Find latest version
uses: oprypin/find-latest-tag@v1
id: latest_version
with:
repository: yungvldai/coursach
releases-only: true
Сначала мы берем наш репозиторий, потом с помощью экшона dante-ev/latex-action компилируем наш tex в PDF, устанавливая main.tex как точку входа. Тут можно пользоваться еще экшоном xu-cheng/latex-action, но с ним с eskdtext были какие-то проблемы.
Затем ищем версию последнего тега, под которым выходил релиз, она пригодится нам позже.
- name: Generate new version
id: new_version
uses: christian-draeger/increment-semantic-version@1.0.2
with:
current-version: ${{ steps.latest_version.outputs.tag }}
version-fragment: 'feature'
- name: Declare some variables
shell: bash
id: some_vars
run: |
echo "##[set-output name=release_name;]$(date +"%d %b %Y at %H:%M")"
Вот нам и пригодилась версия, поднимается ее feature (минорную) часть на 1 с помощью экшона christian-draeger/increment-semantic-version, я использую semver. Что это такое?
Я решил, что мажорную версию буду поднимать в каких нибудь супер случаях (пока не придумал каких), а версии-патчи мне по сути не нужны, но они нужны для того, чтобы этот экшон работал, потому что он не может распознать semver в 1.0
Следует отметить, что первый релиз придется сделать ручками, чтобы экшону было что поднимать, иначе он поднимет панику, а кому это надо.
Далее нам надо прогнать одну команду, чтобы как-то назвать релиз, я решил называть их так:
Release <date> at <time>
GNU date с вернет что то типа 22 Dec 2020 at 14:45 при указании такого формата: +"%d %b %Y at %H:%M", это то, что нужно. Мы помещаем значение в переменную release_name вывода шага some_vars. Потом мы это используем.
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.new_version.outputs.next-version }}
release_name: Release ${{ steps.some_vars.outputs.release_name }}
draft: false
prerelease: false
- name: Upload Release Asset
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./main.pdf
asset_name: coursach.pdf
asset_content_type: application/pdf
Теперь мы создаем новый релиз и выгружаем туда наш скомпилированный PDF, который мы получили на шаге 2 (Compile LaTeX document) с помощью экшонов actions/create-release и actions/upload-release-asset. Мы забираем имя для релиза вот так:
steps.some_vars.outputs.release_name
Это означает что то типа: возьми имя для релиза из поля release_name вывода шага с id=some_vars. Смотрите выше как мы его генерируем.
После этих шагов в вкладке Releases нашего репозитория мы видим:
Единственная проблема - не нашел как подогнать часовой пояс. Сейчас время указывается в GMT+0, то есть время для меня отличается на 3 часа (так как я нахожусь в Петербурге). Ну да пофиг)))
- name: Send e-mail
uses: dawidd6/action-send-mail@v2
with:
server_address: smtp.gmail.com
server_port: 465
username: ${{ secrets.MAIL_USERNAME }}
password: ${{ secrets.MAIL_PASSWORD }}
subject: New coursach release
body: "New release! - <a href='https://github.com/yungvldai/coursach/releases/latest/download/coursach.pdf'>Download now</a>"
to: ${{ secrets.MAILING_LIST }}
from: Deploy Bot
content_type: text/html
Наконец, мы по электронной почте (с помощью dawidd6/action-send-mail) отправляем ссылку на загрузку новейшей версии PDF нашего курсача нашему научнику, а точнее всем, кто указан в secrets.MAILING_LIST (сделано для того, чтобы не светить нашей почтой, а также, чтобы для добавления почты не приходилось менять код). Для этого берется логин и пароль от реально существующей почты, которые я также передаю в secrets. О том как настроить secrets можно почитать тут:
https://docs.github.com/en/free-pro-team@latest/actions/reference/encrypted-secrets
Для теста я указал в MAILING_LIST и себя и каждый раз мне приходит письмо типа:
Ссылка из письма ведет на загрузку документа курсовой работы (точнее ее последнюю версию).
Зачем мне все это?
Это очень удобно. Я могу спокойно писать курсач, вести разработку в разных ветках, править что либо. При этом сохраняется история его написания. Самое крутое то, что как только я посчитаю, что можно показать текущее состояние руководителю, я просто волью ветку в master или сделаю пуш в него и все. Все сделается само. Само соберется, зарелизится и отправится на почту, которую я укажу, а я смогу спокойно идти пить чай и ждать отзыв от научника.
При этом никакой поддержки не требуется, я просто один раз написал конфиг для воркфлоу и все, можно забыть и спокойно писать курсач как будто я делаю это без всего этого.
Самое пугающее здесь - LaTeX, так как нужно уметь с ним работать, но и тут я Вас успокою, потому что понимание приходит спустя ~2 дня работы с ним. Повторюсь, возможно, не очень хороший выбор для курсовых работ и лабораторых, но для диплома (тех. специальности) самое оно.
Приложу, наконец, Вашу любимую кнопку:
Спасибо за внимание и пользуйтесь, оно того стоит.