DevGang
Авторизоваться

🦊 Предварительный просмотр GitLab Pages: бескомпромиссный хак для обслуживания страниц каждой ветки

С помощью GitLab Pages вы можете публиковать статические веб-сайты непосредственно из репозитория в GitLab. По умолчанию у нас не может быть страниц предварительного просмотра: если задание развертывает страницы, это перезаписывает предыдущее содержимое, что запрещает режим предварительного просмотра. Мы покажем как сделать настройку GitLab на примере предварительного просмотра страниц, что облегчит вам работу в будущем.

В некоторых статьях в Интернете показано, как обойти это с помощью артефактов, зная, что GitLab может отображать артефакты. Но у этого трюка есть минусы, в основном узкотехнические ссылки, которыми приходится снова делиться после изменений на ветке.

Некоторая суть Github указывает на правильное направление, но сложным образом и со слишком небольшим количеством побочных функций.

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

Решение можно разбить на следующие шаги:

  • Генерация файлов для текущей ветки
  • Получение предыдущей генерации веток из кэша GitLab
  • Слияние и обновление кэша
  • Автоматическое удаление устаревшего кэша при удалении ветки с использованием среды GitLab

Предпосылки

Мы предполагаем, что у вас уже есть способ создания статического HTML-контента, и вы просто хотите обслуживать файлы с помощью GitLab Pages.

Чтобы код работал, ваш кеш должен быть централизованным, либо с помощью gitlab.com runner, либо с помощью одного исполнителя, либо путем совместного использования кешей несколькими частными исполнителями.

Вам необходимо принять глобальный кэш, отключив опцию GiLab Использовать отдельные кэши для защищенных веток в  Settings->CICD->General Pipelnes.

Код конвейера GitLab

workflow:
  rules: # disable tag pipelines and duplicate MR pipelines
    - if: $CI_COMMIT_BRANCH

variables:
  EPHEMERAL_BRANCHES_PATH: preview # subpath to ephemeral branches content for preview, anything will work

pages:
  stage: build
  image: alpine:3.18
  cache:
    key: gitlab-pages
    paths: [public]
  before_script:
    # default available 'tree' app in alpine image does not work as intended
    - apk add tree
    # CURRENT_CONTENT_PATH is defined in rules, different between main branch and ephemeral branches
    - mkdir -p public/$CURRENT_CONTENT_PATH && ls public/$CURRENT_CONTENT_PATH/..
    - | # avoid deleting main branch content when cache has been erased
      if [ "$CI_COMMIT_BRANCH" != "$CI_DEFAULT_BRANCH" ] && [ ! -d public/$CI_DEFAULT_BRANCH ]; then
        echo -e "💥\e[91;1m Unable to retrieve $CI_DEFAULT_BRANCH generated files from cache ; please regenerate $CI_DEFAULT_BRANCH files first\e[0m"
        exit 1
      fi
    - rm -rf public/$CURRENT_CONTENT_PATH || true # remove last version of current branch
  script:
    - ./generate-my-html.sh --output build-docs || true # insert here your code that generates documentation
    - mv --verbose build-docs public/$CURRENT_CONTENT_PATH
    - cd public/$EPHEMERAL_BRANCHES_PATH
    - tree -d -H '.' -L 1 --noreport --charset utf-8 -T "Versions" -o index.html # generate a root HTML listing all previews for easier access
  environment:
    name: pages/$CI_COMMIT_BRANCH
    action: start
    url: $CI_PAGES_URL/$CURRENT_CONTENT_PATH
    on_stop: pages:clean-preview
  rules:
    # 'main branch' is exposed at GitLab Pages root
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      variables:
        CURRENT_CONTENT_PATH: "."
    # other (short-lived) branches generation are exposed in 'EPHEMERAL_BRANCHES_PATH/branch-name-sanitized' sub path
    - variables:
        CURRENT_CONTENT_PATH: $EPHEMERAL_BRANCHES_PATH/$CI_COMMIT_REF_SLUG
  artifacts:
    paths: [public]
    expire_in: 1h

pages:clean-preview:
  stage: build
  image: alpine:3.18
  cache:
    key: gitlab-pages
    paths: [public]
  variables:
    GIT_STRATEGY: none # git files not available after branch deletion
    FOLDER_TO_DELETE: preview/$CI_COMMIT_BRANCH # an indirection to allow arbirtraty deletion when launching this job
  script:
    - rm -rf public/$FOLDER_TO_DELETE
  environment:
    name: pages/$CI_COMMIT_BRANCH
    action: stop
  rules:
    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
      when: manual
      allow_failure: true

Интегрированные функции

Приведённый выше код имеет следующие функции:

  • main контент отображается на $CI_PAGES_URL, а путь настраивается с помощью $CURRENT_CONTENT_PATH.
  • Контент предварительного просмотра для каждой ветки отображается на $CI_PAGES_URL/preview, а домашняя страница позволяет легко переходить к веткам.
  • Путь к корневой папке предварительного просмотра настраивается с помощью переменной $EPHEMERAL_BRANCHES_PATH, чтобы скрыть содержимое предварительного просмотра путем обфускации.
  • Сгенерированные страницы связаны со средами, чтобы воспользоваться автоматической очисткой при удалении ветки.
  • Чтобы не нарушать уже существующие среды, среда страниц помещается в папку pages.
  • Если main контент не был сгенерирован в текущем кэше или если кэш был удален, срабатывает ошибка, чтобы избежать случайного удаления
  • Задание на удаление может быть запущено вручную с любым путем кэширования в качестве входных данных для очистки устаревших данных.
  • Его можно безопасно добавить в существующий конвейер проекта, не вызывая проблем с уже существующими заданиями.
  • Workflow:rules можно удалить, если у вас уже есть свои, или обновить, чтобы они соответствовали вашему потоку.
  • Задание должно называться pages, а артефакт должен быть общедоступной папкой для развертывания на страницах GitLab (или вы можете использовать ключевое слово pages:publish).

Заключение

Учитывая предоставленный кусок yaml, используя его в своем пайплайне, вы должны иметь возможность делиться своими страницами GitLab для каждой ветки по нужному вам пути, при этом предоставляя стабильный контент из корневого контекста.

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

Источник:

Комментарии
Чтобы оставить комментарий, необходимо авторизоваться