• Русский
  • Настройка сводки Task с помощью шаблонов

    Это руководство показывает, как использовать шаблоны на основе ConfigMap для вывода HTML-отчетов с богатым форматированием на вкладке Overview для ваших TaskRuns и PipelineRuns.

    Вместо того чтобы записывать полный HTML- или Markdown-отчет в один результат Task, ваши Tasks выводят небольшие структурированные метрики, а UI использует шаблон из ConfigMap для формирования итоговой сводки.

    Используйте это руководство, если:

    • Вам нужна единая, аккуратно оформленная сводка для Task (например, сводка проверки кода).
    • Ваша Markdown-сводка приближается к эффективному ограничению размера результата Task или превышает его.
    • Вы хотите повторно использовать один и тот же макет для множества Tasks или кластеров.

    Рендеринг шаблонов — это альтернатива overview-markdown. Если Task по-прежнему выводит результат с именем overview-markdown, UI будет предпочитать этот Markdown и пропускать рендеринг шаблона.

    Предварительные требования

    • Установленный Tekton Pipelines в вашем кластере.
    • Права на создание ConfigMaps в общей пространстве шаблонов kube-public.

    Как это работает

    1. Ваш Task выводит один или несколько результатов, содержащих метрики или сводные данные.
    2. Метаданные вашего Task включают аннотации, которые сообщают UI:
      • Какой ConfigMap следует использовать в качестве шаблона (через селектор label).
      • Какие результаты Task нужно прочитать и передать в шаблон.
    3. UI:
      • Проверяет, есть ли у TaskRun результат с именем overview-markdown. Если да, он отображает этот Markdown и останавливается.
      • В противном случае читает аннотации шаблона из TaskRun.
      • Находит соответствующий ConfigMap и загружает template.ejs.
      • Читает объявленные результаты из TaskRun и объединяет их в один JSON payload.
      • Вычисляет шаблон EJS с этим payload и отображает сгенерированный HTML на вкладке Overview.

    Шаги

    1. Выберите между Markdown и шаблонами

    Используйте результат overview-markdown, если:

    • Содержимое короткое и его легко удержать в пределах ограничений размера результата.
    • Вам нужно только очень простое форматирование.

    Используйте шаблон ConfigMap, если:

    • Вам нужен более сложный макет (колонки, бейджи, прогресс-бары и т. д.).
    • У вас уже есть структурированные метрики, и вы хотите более наглядное представление.
    • Вы хотите, чтобы один макет сводки использовался несколькими Tasks.

    Если настроены оба варианта, приоритет имеет overview-markdown. Вы можете посмотреть вывод шаблона, просто ничего не записывая в результат overview-markdown.

    2. Создайте ConfigMap шаблона

    Создайте ConfigMap, который содержит ваш шаблон EJS и labels, определяющие, к какому Task он относится.

    EJS — это простой язык шаблонов, который позволяет генерировать HTML-разметку с помощью обычного JavaScript. Никакой религиозности в вопросе организации кода. Никакого изобретения итерации и управления потоком заново. Это просто обычный JavaScript. Для получения дополнительных сведений см.:

    Пример:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: my-task-0.1-overview-template
      # configmap should be in kube-public namespace
      namespace: kube-public
      labels:
        # Which Task this template is for
        style.tekton.dev/overview-template-task: my-task
        # Version of the Task/template pairing
        style.tekton.dev/overview-template-task-version: "0.1"
        # Which engine the UI should use
        style.tekton.dev/overview-template-engine: ejs
    data:
      template.ejs: |
        <%
          const m = metrics || {};
          const asNumber = (value, fallback = 0) => {
            const parsed = Number(value);
            return Number.isFinite(parsed) ? parsed : fallback;
          };
        %>
    
        <div style="font:12px sans-serif;margin:8px 0">
          <div style="display:flex;align-items:center;margin-bottom:6px">
            <strong>My Task Summary</strong>
            <% if (m.report_url) { %>
              <a href="<%= m.report_url %>" target="_blank" rel="noreferrer" style="margin-left:8px">
                View report
              </a>
            <% } %>
            <span style="margin-left:auto;color:#5c1">
              Status: <%= m.status || "UNKNOWN" %>
            </span>
          </div>
    
          <div style="display:flex;flex-wrap:wrap;gap:6px;color:#666">
            <div style="flex:1;min-width:110px">
              <b><%= asNumber(m.total) %></b> Total
            </div>
            <div style="flex:1;min-width:110px">
              <b><%= asNumber(m.passed) %></b> Passed
            </div>
            <div style="flex:1;min-width:110px">
              <b><%= asNumber(m.failed) %></b> Failed
            </div>
          </div>
        </div>

    Ключевые моменты:

    • Имя файла шаблона всегда template.ejs.
    • UI будет внедрять переменные из результатов в шаблон.
    • Для простой логики и форматирования можно использовать обычный синтаксис EJS (<% %>, <%= %>).

    3. Добавьте результат в ваш Task

    Определите result в вашем Task, который будет содержать метрики, используемые шаблоном.

    Пример Task:

    apiVersion: tekton.dev/v1
    kind: Task
    metadata:
      name: my-task
    spec:
      results:
        - name: TASK_METRICS
          type: object
          description: Summary metrics for the overview template.
          properties:
            total: {}
            passed: {}
            failed: {}
            status: {}
            report_url: {}
      steps:
        - name: run-and-collect-metrics
          image: <your-image>
          script: |
            #!/usr/bin/env sh
            set -eu
    
            # TODO: replace these with real values
            total=10
            passed=9
            failed=1
            status="OK"
            report_url="https://example.com/report/123"
    
            printf '{"total": "%s", "passed": "%s", "failed": "%s", "status": "%s", "report_url": "%s"}' \
              "$total" \
              "$passed" \
              "$failed" \
              "$status" \
              "$report_url" \
              > "$(results.TASK_METRICS.path)"

    Рекомендации:

    • Делайте результат небольшим и плоским. Используйте простые поля, такие как количество, проценты, статус и URL.
    • Не включайте большие текстовые блоки.
    • Если используете result типа object, убедитесь, что шаг записывает валидный JSON (без завершающих запятых, с корректным экранированием кавычек).

    4. Добавьте аннотации к Task, чтобы связать его с шаблоном

    Используйте аннотации в Task, чтобы сообщить UI, какой шаблон использовать и какие результаты передать в него.

    Пример для одного результата:

    apiVersion: tekton.dev/v1
    kind: Task
    metadata:
      name: my-task
      annotations:
        # 1) Where to find the template ConfigMap
        style.tekton.dev/overview-template-selector: >
          style.tekton.dev/overview-template-task=my-task,
          style.tekton.dev/overview-template-task-version=0.1
    
        # 2) Which Task result(s) to read from the TaskRun
        #    Here: expose TASK_METRICS as "metrics" in template.ejs
        #    If you do not specify an alias key, the result name is used (TASK_METRICS).
        style.tekton.dev/overview-template-result-key: TASK_METRICS:metrics
        
    spec:
      results:
        - name: TASK_METRICS
          type: object
      steps:
        - name: run-and-collect-metrics
          image: <your-image>
          # ...

    Концептуально UI сформирует payload примерно такого вида:

    {
      "metrics": {
        "total": "10",
        "passed": "9",
        "failed": "1",
        "status": "OK",
        "report_url": "https://example.com/report/123"
      }
    }

    Затем он вычислит template.ejs с этим payload, чтобы вы могли использовать metrics.total, metrics.status и так далее.

    Вы можете объединить несколько результатов Task в один рендеринг шаблона. Это полезно, когда:

    • Один результат содержит метрики.
    • Другой результат содержит URL полного отчета.

    Пример:

    metadata:
      annotations:
        style.tekton.dev/overview-template-selector: >
          style.tekton.dev/overview-template-task=sonarqube-scanner,
          style.tekton.dev/overview-template-task-version=0.5
    
        # Multiple results, separated by commas
        # Aliases:
        # - CODE_SCAN_METRICS -> metrics
        # - SCAN_RESULT_URL   -> SCAN_RESULT_URL (no alias)
        # - SCAN_PROJECT      -> SCAN_PROJECT (no alias)
        style.tekton.dev/overview-template-result-key: |
          CODE_SCAN_METRICS:metrics,SCAN_RESULT_URL,SCAN_PROJECT

    UI сформирует payload, похожий на следующий:

    {
      "metrics": {
        "bugs": "2",
        "vulnerabilities": "1"
      },
      "SCAN_RESULT_URL": "https://devops-sonar.example.net/dashboard?id=project&branch=main",
      "SCAN_PROJECT": ["foo", "bar"]
    }

    5. Запустите Task и проверьте вкладку Overview

    1. Примените ConfigMap и Task в ваш кластер.

    2. Создайте TaskRun или PipelineRun, который использует этот Task, например:

      apiVersion: tekton.dev/v1
      kind: TaskRun
      metadata:
        name: my-task-run
      spec:
        taskRef:
          name: my-task
    3. Дождитесь завершения запуска.

    4. Откройте запуск в UI и выберите вкладку Overview.

    Если все настроено правильно, вы увидите HTML, сгенерированный вашим шаблоном.

    Если Task также выводит overview-markdown, вместо шаблона будет показан Markdown.

    Советы и соглашения

    • Предпочитайте небольшой result с метриками. Рассматривайте результаты как компактную сводку.
    • Делайте логику шаблона простой. Сосредоточьтесь на представлении, а не на бизнес-логике. Избегайте тяжелых вычислений в шаблоне.
    • Защищайтесь от отсутствующих данных. Используйте значения по умолчанию в шаблоне, чтобы отсутствующие поля не приводили к сбою рендеринга.

    Устранение неполадок

    Во вкладке Overview ничего не отображается

    • Выводит ли Task пустой overview-markdown?
      • Если да, UI покажет этот пустой Markdown и проигнорирует шаблоны. Вы можете увидеть вывод шаблона, просто ничего не записывая в результат overview-markdown.
    • Содержит ли TaskRun результат(ы), перечисленные в overview-template-result-key?
      • Проверьте YAML TaskRun и .status.results.
    • Совпадает ли селектор в overview-template-selector ровно с одним ConfigMap в namespace kube-public?
      • Проверьте это с помощью kubectl get configmap -l <your-selector> -n kube-public.

    Шаблон рендерится, но данные пустые или неправильные

    • Если вы используете result типа object, убедитесь, что результат валиден и содержит поля, которые ожидает ваш шаблон.
    • Проверьте, что имена в overview-template-result-key точно совпадают с именами результатов Task.

    Ограничения на размер результата или termination message

    • Удалите из результатов несущественные поля.
    • Перенесите подробные отчеты по каждому файлу в логи или внешнюю систему, а в результатах оставляйте только итоговые числа и URL.
    • Помните, что каждый Task по-прежнему использует единый бюджет termination-message для всех шагов и результатов.
    • Modify result limit

    Выбран неправильный шаблон

    • Убедитесь, что overview-template-selector достаточно специфичен (например, включает и имя Task, и версию).
    • Не используйте одни и те же labels для несвязанных шаблонов.
    • Если селектору соответствуют несколько ConfigMaps, уточните labels так, чтобы выбирался только один ConfigMap.

    Как только у вас будут ConfigMap шаблона, результаты с метриками и правильные аннотации Task, вы сможете создавать повторно используемые, версионируемые макеты сводки Task без изменения самого UI.