5  Публикация веб-документов

Существует множество способов публикации документов, презентаций и веб-сайтов, созданных с помощью Quarto, на различных популярных сервисах (например, Github Pages, Netlify, Quarto Pub, Hugging Faces и т. д.), а также различных инструментов для публикации из системы непрерывной интеграции (continuous integration - CI).

Замечание

Отметим, что в простых случаях публикации, таких как Netlify Drop, публикация материалов происходит достаточно просто — простым перетягиванием папки в область на сайте провайдера, либо, как это сделано, скажем, в Quarto Pub, используя командную строку с помощью команды публикации quarto publish. Тем не менее, в конечном итоге мы будем ориентироваться на работу с системой Git и автоматизированную публикацию материалов. Преимущества работы с Git состоят в том, что использование Git дает возможность работать нескольким авторам с одним и тем же документом, отслеживать версии документа, сохраняя их, а для публикации Quarto-проектов — автоматизации процесса публикации. Если вносятся изменения в Quarto-документ, Git позволяет сохранять эти изменения как commit, а когда в последующем эти изменения фиксируются как push, все эти изменения автоматически отражаются на сайте, что является весьма удобным, т. е. сайт автоматически обновляется при выполнении каждой команды push. В дополнение, система CI позволяет настроить рабочий процесс выполняя все действия в облаке провайдера.

Перед тем, как рассмотреть различные виды публикации, отметим несколько общих моментов.

  1. До того, как опубликовать тот или иной документ, необходимо предварительно сделать его рендер командой quarto render.
  2. HTML-документы обычно имеют ряд внешних зависимостей (например, изображения, таблицы стилей CSS, JavaScript и т.д.), и по умолчанию Quarto помещает эти зависимости в папку _files (например, _site или _book) в том же каталоге, что и ваш *.qmd-файл. Если вы публикуете HTML-файл на хостинговой платформе, зависимости в этом каталоге публикуются вместе с вашим документом и, следовательно, доступны в опубликованном отчете.
  3. Могут быть случаи, когда предпочтительнее автономный HTML-документ, который встраивает все свои зависимости. Это можно сделать, указав опцию embed-resources: true. Полученный файл будет автономным, то есть для его корректного отображения в браузере не потребуются никакие внешние файлы и доступ в Интернет.
# весь контент будет объединен в один HTML-файл
format:
  html:
    embed-resources: true
  1. Важно понимать разницу между различными типами публикации в зависимости от того, где и как осуществляется рендеринг отдельного документа или проекта Quarto: локально или публикация полученного контента будет осуществляться автоматически всякий раз, когда вы отправляете изменение исходного кода в свой репозиторий. В том случае, если используется автоматизация публикации, то необходимо обязательно выполнить команду quarto publish <service_name> с названием сервиса публикации, что создаст файл _publish.yml со значениями id и url для вашего сайта. Также, перед выполнением команды quarto render (а после нее quarto publish), чтобы убедиться, что код R, Python или Julia выполняется только локально, можно настроить проект на использование функции заморозки (freeze) в Quarto, добавив в файл _quarto.yml следующее:
_quarto.yml
# повторный рендеринг выполняется только при изменении исходного кода
execute:
  freeze: auto 
  1. Автоматизация общего процесса публикации складывается из рендера проекта и публикации проекта. Мы рассмотрим упрощенный вариант публикации, более подробно про автоматизацию с участием Github Actions можно почитать на странице Github Actions for Quarto.

Создадим небольшой проект на основе шаблона, немного видоизменим его и далее рассмотрим различные варианты публикации. Пусть это будет пример небольшого блога, созданного с помощью команды, как это показано ниже, либо в IDE.

Terminal
quarto create-project --type website:blog

5.1 Публикация проектов на Quarto Pub

Сервис Quarto Pub — это бесплатный сервис от Posit PBC, позволяющий публиковать сайты до 100 МБ с лимитом пропускной способности в 10 ГБ в месяц.

Рисунок 5.1: Начальная страница сервиса Quarto Pub

Сначала необходимо зарегистрироваться на сайте.

Рисунок 5.2: Страница регистрации

После регистрации можно публиковать свои проекты.

Рисунок 5.3: Начальная страница сервиса Quarto Pub после регистрации

Мы готовы к публикации блога, для этого в папке, в которой находится проект, необходимо в терминале сначала сделать рендер проекта командой quarto render, а затем выполнить команду:

Terminal
quarto publish quarto-pub 

Будет предложено авторизоваться на сайте и выбрать имя сайта (рекомендуется вводить имя сайта латиницей).

Рисунок 5.4: Пример публикации сайта на сервисе Quarto Pub

Теперь откроется страница с публикацией блога.

Рисунок 5.5: Пример публикации сайта на сервисе Quarto Pub

Здесь мы можем назначить наш сайт по умолчанию для своей учетной записи (https://username.quarto.pub) или полностью его удалить.

Рисунок 5.6: Обзор опубликованных сайтов на Quarto Pub

Отметим, что при публикации будет создан файл _publish.yml, который в нашем случае выглядит так:

_publish.yml
- source: project
  quarto-pub:
    - id: 1a854318-ad2d-4564-acbf-d9d3927181fb
      url: 'https://quarto-publishing-book.quarto.pub/blogexample'

Можно открыть сайт, который мы опубликовали. Более углубленно можно познакомиться с публикацией проектов с помощью Quarto Pub на странице документации.

5.2 Публикация проектов на Posit Connect Cloud

Posit Connect Cloud от Posit — относительно новый сервис, альфа-версия которого вышла в июле 2024 года. Данный сервис настроен на то, чтобы публиковать приложения и документы самых различных типов, включая как R, так и Python-решения на основе единой платформы. Сервис в первую очередь подходит для публикации интерактивных приложений (Streamlit, Shiny и т.д.), однако здесь также присутствует возможность публиковать Quarto-документы. Кратко опишем процесс публикации.

Рисунок 5.7: Начальная страница Posit Connect Cloud

Для публикации нам понадобится проект, который выложен в открытый репозиторий на GitHib. Пусть у нас уже имеется репозиторий соответствующий примеру блога. Предположим, что мы уже выполнили команду quarto render, результатом является созданная папка _site для публикации, которая размещена на GitHub. Также, предположим, что у нас имеются элементы кода R внутри проекта. В этом случае нужно создать файл manifest.json в том же каталоге, что и проект для указания зависимостей библиотек и указания версии R, это можно сделать как написано в руководстве с помощью следующей команды, находясь в текущем каталоге в RStudio или Positron:

R
library(rsconnect)
writeManifest()

В случае, если основной код проекта написан на Python, необходимо установить зависимости библиотек в файле requirements.txt, как это описано в руководстве. Убедившись, что после создания manifest.json и соответствующего коммита все находится на GitHub, можно приступать к публикации проекта. Для этого нужно зайти через свой GitHub-account на https://connect.posit.cloud/ и перейти Go to your content : Publish.

Рисунок 5.8: Страница публикации на Posit Connect Cloud

Затем выбираем Select your framework : Quarto, репозиторий (например, quarto-publish-posit-cloud), ветку (main), Primary file (index.qmd) и нажимаем кнопку Publish. Происходит процесс публикации:

Рисунок 5.9: Публикация проекта на Posit Connect Cloud

Каждый опубликованный контент добавляется в ваш личный профиль.

Рисунок 5.10: Опубликованный проект на Posit Connect Cloud

5.3 Публикация проектов на GitHub Pages

Если вы работаете в области IT-технологий с проектами, требующими контроль версий, то одной из основных технологий, которая используется для совместной разработки, является система контроля версий Git. Система Git поддерживает разделение или слияние версий, предоставляет полную историю разработки и позволяет каждому разработчику сохранять локальную копию всей истории разработки с возможностью синхронизации, отслеживая только внесенные изменения.

Одна из наших последующих целей — рассмотреть процесс автоматизации публикации Quarto-проектов на основе сервисов Git. Фиксируя каждое изменение в текстовом файле как commit с его описанием, мы получаем “машину времени”, хранящую все версии файла, которые легко передать соавтору. С другой стороны, оформив изменения как commit и далее отправив локальную ветку на удаленный репозиторий, можно настроить при этом автоматическое обновление сайта без внешнего вмешательства. Последний способ является привлекательным, но зависит от того, как будут исполняться рендер и код — локально или на сайте Git-провайдера. Процесс публикации схематично изображен на рисунке ниже.

%% https://mermaid.js.org/syntax/flowchart.html
flowchart LR
    classDef blueclass stroke:#00f
    classDef blackclass stroke:#000,stroke-width:1px
    subgraph subgraph1["`**Quarto документ**`"]
        direction TB
        author1("`Автор 1`"):::blackclass <--> author2("`Автор 2`"):::blackclass
        author2("`Автор 2`"):::blackclass <-.-> authorn("`Автор n`"):::blackclass
    end
    subgraph subgraph2["`**<i class="fa-brands fa-git-alt"></i> Git**`"]
        direction LR
        commit[fa:fa-code-branch commit]:::blackclass ---> github["<i class="fa-brands fa-github"></i> GitHub"]
        commit[fa:fa-code-branch commit]:::blueclass ---> gitlab["<i class="fa-brands fa-gitlab"></i> GitLab"]
        commit[fa:fa-code-branch commit]:::blueclass ---> bitbucket["<i class="fa-brands fa-bitbucket"></i> Bitbucket"]
    end
    subgraph subgraph3["`**<i class="fa-brands fa-chrome"></i> Web-публикация**`"]
        direction TB
        netlify[Netlify и т.п.]:::blackclass 
        githubpages["GitHub Pages"]:::blackclass 
    end

    subgraph1 --> commit
    
    github ---> githubpages
    github ---> netlify
    gitlab ---> netlify
    bitbucket ---> netlify
Рисунок 5.11: Рабочий процесс публикации проектов Quarto на основе Git

5.3.1 Публикация на Github Pages из репозитория

Шаг 1. Создадим публичный репозиторий на GitHub, предполагаем, что создана и настроена учетная запись. Отметим, что если репозиторий называется repository_name (можно выбрать свое название), тогда ваш сайт будет называться https://your_github_name.github.io/repository_name.

Рисунок 5.12: Пример создания репозитория на GitHub

Далее необходимо сделать локальное клонирование репозитория, либо с помощью команды git clone <repository> <directory>. Если на компьютере установлено приложение GitHub Desktop, другой простой способ клонирования проекта — на на веб-странице только что созданного созданного проекта нужно нажать на кнопку Quick setup в разделе Set up in Desktop, тогда откроется GitHub Desktop, в меню которого необходимо указать путь для клонирования репозитория и нажать кнопку Clone. Можно использовать иной Git-клиент для клонирования репозитория.

Рисунок 5.13: Пример созданного репозитория на GitHub

Далее необходимо перейти к папке, куда было произведено клонирование, и создать проект внутри папки аналогично тому, как это было сделано выше.

Шаг 2. Сконфигурируем директорию docs для публикации материалов.

_quarto.yml
project:
  type: website
  output-dir: docs

Затем необходимо добавить файл .nojekyll в корневой каталог вашего репозитория, который сообщает страницам GitHub не выполнять дополнительную обработку опубликованного сайта с помощью Jekyll (инструмент создания сайтов на GitHub по умолчанию):

Terminal
touch .nojekyll
Terminal
copy NUL .nojekyll

Выполняем quarto render в папке проекта в терминале и добавляем созданную папку docs в репозиторий:

Terminal
quarto render
git add docs

После всех предварительных действий можно зафиксировать коммит и отправим локальную ветку на удаленный репозиторий, что можно сделать либо из терминала либо в GitHub Desktop.

Terminal
git commit -m "новый блог! :tada:"
git push
Рисунок 5.14: Пример фиксации изменений репозитория в GitHub Desktop

Шаг 3. Убедимся что изменения в репозитории опубликованы, для этого перейдем на сайт.

Рисунок 5.15: Пример репозитория для публикации на GitHub Pages

Переходим на вкладку настроек Settings репозитория и выбираем Pages и далее находим Build and deployment : Source : Deploy from a branch. В разделе Build and deployment : Branch выбираем ветку (в нашем случае main), директорию (Select folder : /docs) и нажимаем Save, что завершает процесс публикации.

Рисунок 5.16: Пример настроек репозитория для публикации на GitHub Pages

После перезагрузки страницы появится адресная строка созданного проекта. Если в дальнейшем в файлы проекта будут вноситься изменения, а затем с помощью последовательности рендер проекта –> коммит –> push на GitHub фиксироваться, то все изменения автоматически вступят в силу и на сайте.

5.3.2 Автоматизированная публикация проектов на GitHub Pages с помощью GitHub Actions

Кратко опишем шаги для автоматизированного создания и публикацию сайта с помощью GitHub Actions. Как и ранее, создадим репозиторий и клонируем его локально. Разместим в локальной папке с репозиторием проект, который содержит файлы index.qmd и _quarto.yml. Также разместим в корневом каталоге файл .nojekyll:

Terminal
touch .nojekyll
Terminal
copy NUL .nojekyll

Далее создадим директорию .github/workflows, в которой нужно разместить файл publish-quarto.yml, содержащий:

publish-quarto.yml
name: Quarto Publish
on:
  workflow_dispatch:
  push:
    branches: main

jobs:
  build-deploy:
      runs-on: ubuntu-latest
      permissions:
        contents: write
     steps:
      - name: Check out repository
        uses: actions/checkout@v4

      - name: Set up Quarto
        uses: quarto-dev/quarto-actions/setup@v2

      - name: Render and Publish
        uses: quarto-dev/quarto-actions/publish@v2
        with:
          target: gh-pages
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Совет

Для ежедневных проверок можно установить расписание:

publish-quarto.yml
on:
  push:
    branches: main
  pull_request:
    branches: main
  schedule:
    # запускается ежедневно в 12:00
    - cron: '0 12 * * *'

Также в преамбулу файла index.qmd необходимо добавить

index.qmd
---
resources:
  - .nojekyll
---

В файл _quarto.yml необходимо добавить

index.qmd
project:
  type: website
  output-dir: docs
execute:
  freeze: auto

Теперь можно сделать рендер проекта командой quarto render в корневой директории проекта, после чего можно добавить все файлы рабочего каталога в индекс для последующего коммита (например, как git add .), сделать коммит и git push чтобы отправлять локальную ветку на удаленный репозиторий.

Как и в предыдущем случае, необходимо вернуться в веб-браузер и создать новую ветку gh-pages в настройках репозитория. Для этого на веб-странице репозитория нужно выбрать в выпадающем меню (main) с указанием веток View all branches : New branch, указать New branch name и ввести gh-pages. Далее нужно выбрать Settings : Pages, выбрать Deploy from branches, в разделе Branch указать gh-pages /docs и нажать Save. Теперь любые Git-изменения будут автоматизированы, нет необходимости делать локальный рендер, все будет выполняться на сайте.

5.4 Публикация проектов на Netlify

Netlify — это одна из наиболее популярных платформ для веб-разработки, помогающая публиковать различные проекты в сети Интернет, которая хорошо подходит для индивидуального использования или небольших команд. Netlify предоставляет множество сервисов, включая рабочие процессы на основе Git, интерфейс командной строки Netlify CLI и многое другое. Привлекательным является довольно простой процесс публикации с помощью Netlify, множество настроек, возможность публикации из приватных репозиториев, многие функции по умолчанию доступны бесплатно (например, предоставление домена) и т. д.

Рисунок 5.17: Начальная страница сервиса Netlify

Мы рассмотрим три возможности: публикацию с помощью Netlify Drop — простой интуитивный способ публикации для ручного развертывания статических веб-сайтов, публикацию сайтов с помощью связывания их с имеющимся репозиторием и непрерывное развертывание, которое работает путем подключения репозитория Git к сайту Netlify и поддержания их синхронизации.

Перейдя на начальную страницу Netlify необходимо связать свой account на одном из сервисов (GitHub, GitLab или Bitbucket) с Netlify.

Рисунок 5.18: Страница регистрации на Netlify

После регистрации откроется страница, на которой можно увидеть все настройки, а также веб-страницы, размещенные с помощью Netlify.

Рисунок 5.19: Страница настроек на Netlify

5.4.1 Публикация с помощью Netlify Drop

Один из самых простых и быстрых способов публикации простых сайтов, созданных в Quarto, — это сервис Netlify Drop, доступный либо через выбор Add new site : Deploy manually на странице настроек Netlify, либо на сайте Netlify Drop.

Рисунок 5.20: Страница Netlify Drop

Используем созданный ранее проект блога для публикации. После рендеринга в текущей папке должна появиться папка _site, которую будем использовать для публикации. Отметим, что для книги создастся папка _book, кроме того, важно чтобы папка для публикации содержала основной файл index.html, даже если проект включает один файл *.qmd для рендеринга. Если все условия выполнены, достаточно перетащить папку в область публикации в Netlify Drop для создания веб-страницы. После публикации можно зайти в раздел Site configuration : Change site name чтобы изменить адрес страницы на подходящий https://your-address.netlify.app/.

Рисунок 5.21: Пример изменения адреса опубликованного сайта на странице конфигурации Netlify Drop

При наличии изменений сайт возможно обновить тем же способом вручную. Такой способ является быстрым и простым, но, вместе с тем, лишен автоматизации, о чем мы поговорим ниже.

5.4.2 Публикация на Netlify с синхронизацией Git-репозитория

Нетрудно настроить развертывание веб-сайтов на Netlify с использованием готовых репозиториев. Весь процесс выглядит достаточно просто: сначала нужно создать Quarto-проект и в терминале корневого каталога проекта набрать quarto render. Пусть во время рендера была создана папка _site.

Затем на странице настроек Netlify нужно нажать на кнопку Add new site : Import an existing project и выбрать Git-провайдера: GitHub, GitLab, Bitbucket или Azure DevOps, в первый раз понадобится авторизация.

Рисунок 5.22: Выбор Git-провайдера на Netlify

Пусть в нашем случае это будет GitHub (причем, репозиторий может быть и приватным).

Рисунок 5.23: Выбор GitHub-репозитория на Netlify

Перейдя далее нужно найти раздел Publish directory и указать _site (либо _book или аналогичную директорию), а также выбрать ветку для публикации.

Рисунок 5.24: Этап выбора базовой директории при публикации на Netlify

Кроме того, на этой же странице можно выбрать в разделе Site name название сайта в формате https://sitename.netlify.app. Достаточно нажать на кнопку Deploy для публикации проекта.

Рисунок 5.25: Пример настроек опубликованного веб-сайта на Netlify

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

В Netlify можно установить эмблему состояния рабочего процесса, показывающую статус публикации, перейдя на Site configuration : General : Status badges и далее выбрав Deploy status badge. Например, для данной книги эмблема выглядит так: Netlify Status.

5.4.3 Публикация на Netlify с использованием GitHub Actions

Рассмотрим возможность публикации проекта на Netlify используя проекты на Git-провайдерах без участия локального рендеринга с помощью continuous integration (CI). Данный способ публикации, помимо автоматизации, хорош также тем, что позволяет не задействовать директорию _site, где хранится рендер проекта, сократив как время на публикацию, так и объем коммита, однако нужно помнить, что Netlify по мере создания и запуска сборок в вашей учетной записи будет учитывать использование минут сборки (Build minutes), на бесплатном плане предоставляется не более 300 минут в месяц (на момент написания этого текста). Минуты сборки включают время, необходимое Netlify для выполнения инструкций в ваших сценариях сборки и развертывания вашей сборки.

Первый шаг аналогичен тому, как и в предыдущем случае: создаем GitHub репозиторий, клонируем с помощью командной строки либо через приложение (например, GitHub Desktop) в локальную папку и создаем там проект. Отметим, что можно сначала создать проект локально, а затем связать его с GitHub-репозиторием.

Затем нужно заморозить вычисления кода, чтобы они выполнялись только локально. Когда мы будем делать рендер проекта, результаты выполнения кода сохраняются в html.json-файле в каталоге _freeze. Следовательно, каталог _freeze и все его файлы должны быть зафиксированы в нашем репозитории. В противном случае сборка завершится неудачей, поскольку у Netlify нет результата выполнения кода, и он не может выполнить код без установленного R/Python/Julia.

_quato.yml
execute:
  freeze: auto

Настройка freeze: auto указывает Quarto, что нужно повторно рендерить код только при изменении исходного кода. Теперь необходимо сделать хотя бы один локальный рендер проекта командой quarto render в корневом каталоге проекта, тогда в случае наличия исполняемого кода появится папка _freeze. Публикуем проект на Netlify также, как это было рассмотрено в предыдущем пункте.

Следующий этап — установка плагина Quarto Netlify, позволяющий собирать проекты Quarto на Netlify. Для этого в корневой каталог проекта нужно добавить два файла:

package.json
{
    "dependencies": {
        "@quarto/netlify-plugin-quarto": "^0.0.5"
    }
}
netlify.toml
[[plugins]]
package = "@quarto/netlify-plugin-quarto"

Поскольку мы хотим, чтобы роботы Netlify использовали непрерывное развертывание для создания нашего сайта, нам нужно игнорировать наш выходной каталог. Для этого мы добавляем каталог _site, содержащий все отображаемое содержимое веб-сайта, в наш файл .gitignore. Это рекомендуется в документации Quarto, чтобы избежать запутанных добавляемые изменений и потенциальных конфликтов при слиянии.

.gitignore
/_site/

Фиксируем все эти вводные как commit / push на удаленный сервер, сайт также опубликуется. Далее необходимо связать сайт с Git-репозиторием. Это делается из настроек сайта на Netlify перейдя в раздел Site configuration : Build & deploy : Continuous deployment, здесь необходимо нажать на Link repository.

Следующие этапы: 1. Connect to Git provider, где выбирается провайдер с Git-репозиторием (в нашем случае это GitHub), 2. Select repository, где мы выбираем исходный репозиторий, 3. Configure site and deploy, где выбираются ветка и Publish directory — в нашем случае это _site. После нажатия кнопки Deploying your_repository_name сайт публикуется. Теперь можно проверить работоспособность сайта, внеся изменения и зафиксировав их.

Отметим, что если мы больше не хотим, чтобы выполнялась автоматическая публикация сайта, то можно ее отключить, для этого нужно в разделе Deploys нажать на кнопку Lock to stop autopublishing.

Рисунок 5.27: Настройки автоматической публикации на Netlify

Сайт будет по-прежнему публиковаться каждый раз, когда вы отправляете изменения в свой репозиторий, но вам нужно нажать кнопку, чтобы фактически опубликовать это последнее развертывание. Это хороший вариант, если вы не хотите работать в новых ветвях или использовать запросы на извлечение/слияния, но все равно хотите предварительно просмотреть свой сайт перед его отправкой в deployment.

Данный способ публикации работает и с Reveal.js-презентациями, только нужно добавить в каталог проекта файл _quarto.yml следующего содержания после создания презентации:

_quarto.yml
project:
  type: website
  output-dir: _site

execute:
  freeze: auto

Заключение

Мы рассмотрели несколько различных способов публикации веб-документов Quarto на различных популярных платформах, таких как GitHub Pages, Netlify и Quarto Pub, привели детальные руководства по настройке автоматизированного процесса публикации, остановившись как на простых способах процесса публикации, так и на автоматизированном процессе публикации с помощью систем контроля версий Git.

Более подробно о процессе публикации можно посмотреть на странице документации. Например, нами не были охвачены варианты публикации на платформах Atlassian Confluence и Hugging Face Spaces. Каждый сможет найти для себя предпочтительный способ хостинга веб-сайтов для обновления и публикации контента с минимальными усилиями.