Workflow Variables#

Workflow Templates#

Underlying the CLI, the PTB uses Jinja to dynamically generate project-specific workflows. The rendering process is supported by the github_template_dict found in your noxconfig.py::PROJECT_CONFIG. This dictionary is inherited by default from exasol.toolbox.config.BaseConfig.github_template_dict, ensuring a standardized baseline that can be overridden in individual projects.

    def github_template_dict(self) -> GithubTemplateContext:
        """
        Dictionary of variables to dynamically render Jinja2 templates into valid YAML
        configurations.
        """
        from exasol.toolbox.util.workflows.custom_workflow_extractor import (
            CustomWorkflowExtractor,
        )

        custom_workflow_extractor = CustomWorkflowExtractor(
            github_workflow_directory=self.github_workflow_directory,
            sonar_token_name=self.sonar_token_name,
        )

        return GithubTemplateContext(
            custom_workflows=custom_workflow_extractor.build_custom_workflow_dict(),
            dependency_manager_version=self.dependency_manager.version,
            has_documentation=self.has_documentation,
            minimum_python_version=self.minimum_python_version,
            os_version=self.os_version,
            python_versions=self.python_versions,
            sonar_token_name=self.sonar_token_name,
            workflow_header=f"{WORKFLOW_HEADER_PREFIX}{__version__}.",
        )

Custom Workflow Metadata#

The PTB extracts metadata from reusable custom workflow files and exposes it through exasol.toolbox.config.BaseConfig.github_template_dict under the custom_workflows entry. PTB-controlled workflow templates use that metadata when they call reusable workflows.

Secrets#

The PTB extracts the names of secrets from custom workflow files and exposes them through exasol.toolbox.config.BaseConfig.github_template_dict under the custom_workflows entry. PTB-controlled workflow templates use those extracted names when they call reusable workflows and forward secrets via secrets:.

To make a custom workflow compatible with this extraction, declare its secrets at the top of the reusable workflow file under on.workflow_call and before jobs. The extractor reads that section and collects the secret names automatically.

For example, slow-checks.yml can define its reusable workflow header like this:

name: Slow-Checks

on:
  workflow_call:
    secrets:
      PYPI_TOKEN:
        required: true
      SONAR_TOKEN:
        required: true

Those extracted secret names are then made available to the PTB templates that reference the custom workflow.

Permissions#

The PTB extracts the permissions required by custom workflow files. It reads every job’s permissions block and combines the results into a single ordered mapping, where the most permissive level wins.

Please only configure the minimum required permissions by granting the least required access. In practice, contents: read is the most common baseline for workflows, and other permissions should only be added when it is truly required.

For example, a custom workflow can declare permissions like this:

name: Slow-Checks

on:
  workflow_call:

jobs:
  run-integration-tests:
    permissions:
      contents: read

Matrix Combinations#

The matrix.yml is used to generate different combinations of workflow inputs, such as Python versions, Exasol versions, and any project-specific values exposed by the config. This lets the PTB render workflows from a single matrix definition instead of maintaining separate variants.

Extending the Matrix#

If you need to expose additional values via the matrix.yml, you can extend exasol.toolbox.config.BaseConfig.

The example adds two additional matrix dimensions: A declared one extra_matrix_value and a computed one computed_matrix_value. Each of them returning only a simple string value.

PTB’s Nox task generate:matrix will then be able to use each of the these dimensions when generating a build matrix.

from pydantic import computed_field

from exasol.toolbox.config import BaseConfig


class Config(BaseConfig):
    extra_matrix_value: str = "extra"

    @computed_field  # type: ignore[misc]
    @property
    def computed_matrix_value(self) -> str:
        # This can be requested when generating the matrix. If it is a simple
        # string value, like is shown here, the generator wraps it in an array.
        return f"{self.project_name}-computed"

You can consume the additional value in a workflow by passing the relevant matrix_keys_json entries when calling matrix.yml:

jobs:
  build-matrix:
    uses: ./.github/workflows/matrix.yml
    with:
      matrix_keys_json: '["extra_matrix_value","computed_matrix_value"]'