From be18a308e006f0b0af1431058724d257160528ac Mon Sep 17 00:00:00 2001 From: Ariel Schulz Date: Thu, 18 Jun 2026 13:33:27 +0200 Subject: [PATCH 01/13] Remove as no secret needed here --- exasol/toolbox/templates/github/workflows/slow-checks.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/exasol/toolbox/templates/github/workflows/slow-checks.yml b/exasol/toolbox/templates/github/workflows/slow-checks.yml index b15394bfa..487268d1b 100644 --- a/exasol/toolbox/templates/github/workflows/slow-checks.yml +++ b/exasol/toolbox/templates/github/workflows/slow-checks.yml @@ -21,8 +21,6 @@ jobs: runs-on: "(( os_version ))" permissions: contents: read - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} strategy: fail-fast: false matrix: ${{ fromJson(needs.build-matrix.outputs.matrix) }} From 14b547cf4d0fa19fa440cb4f4a6fcc0e1f7cfbbc Mon Sep 17 00:00:00 2001 From: Ariel Schulz Date: Thu, 18 Jun 2026 13:33:41 +0200 Subject: [PATCH 02/13] Add initial slow-checks secret modifier --- .github/workflows/merge-gate.yml | 1 - .github/workflows/periodic-validation.yml | 1 - exasol/toolbox/config.py | 10 ++++++++++ .../toolbox/templates/github/workflows/merge-gate.yml | 7 ++++++- .../templates/github/workflows/periodic-validation.yml | 7 ++++++- 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/.github/workflows/merge-gate.yml b/.github/workflows/merge-gate.yml index 39fb7ee9d..aa3e3e29b 100644 --- a/.github/workflows/merge-gate.yml +++ b/.github/workflows/merge-gate.yml @@ -47,7 +47,6 @@ jobs: needs: - approve-run-slow-tests uses: ./.github/workflows/slow-checks.yml - secrets: inherit # zizmor: ignore[secrets-inherit] - PTB cannot customize inherited secrets here yet; tracked in https://github.com/exasol/python-toolbox/issues/872. permissions: contents: read diff --git a/.github/workflows/periodic-validation.yml b/.github/workflows/periodic-validation.yml index 01b25f5b3..62834750f 100644 --- a/.github/workflows/periodic-validation.yml +++ b/.github/workflows/periodic-validation.yml @@ -46,7 +46,6 @@ jobs: uses: ./.github/workflows/slow-checks.yml needs: - restrict-to-default-branch - secrets: inherit # zizmor: ignore[secrets-inherit] - PTB cannot customize inherited secrets here yet; tracked in https://github.com/exasol/python-toolbox/issues/872. permissions: contents: read diff --git a/exasol/toolbox/config.py b/exasol/toolbox/config.py index 4e7211342..fccfad0a3 100644 --- a/exasol/toolbox/config.py +++ b/exasol/toolbox/config.py @@ -207,6 +207,12 @@ class BaseConfig(BaseModel): are supported. """, ) + secrets_slow_checks: tuple[str, ...] = Field( + default=(), + description="""This tuple defines the string names of secrets needed to pass + to the slow-checks.yml. + """ + ) @computed_field # type: ignore[misc] @property @@ -336,6 +342,10 @@ def github_template_dict(self) -> dict[str, Any]: "fast_tests": fast_tests_extension.is_file(), "merge_gate": merge_gate_extension.is_file(), }, + "secrets": + { + "slow_checks": self.secrets_slow_checks, + } } @computed_field # type: ignore[misc] diff --git a/exasol/toolbox/templates/github/workflows/merge-gate.yml b/exasol/toolbox/templates/github/workflows/merge-gate.yml index a7498dd92..cdd3f60f9 100644 --- a/exasol/toolbox/templates/github/workflows/merge-gate.yml +++ b/exasol/toolbox/templates/github/workflows/merge-gate.yml @@ -46,7 +46,12 @@ jobs: needs: - approve-run-slow-tests uses: ./.github/workflows/slow-checks.yml - secrets: inherit # zizmor: ignore[secrets-inherit] - PTB cannot customize inherited secrets here yet; tracked in https://github.com/exasol/python-toolbox/issues/872. + (% if secrets.slow_checks %) + secrets: + (% for secret_name in secrets.slow_checks %) + (( secret_name )): ${{ secrets.(( secret_name )) }} + (% endfor %) + (% endif %) permissions: contents: read diff --git a/exasol/toolbox/templates/github/workflows/periodic-validation.yml b/exasol/toolbox/templates/github/workflows/periodic-validation.yml index 34f78370c..99368728f 100644 --- a/exasol/toolbox/templates/github/workflows/periodic-validation.yml +++ b/exasol/toolbox/templates/github/workflows/periodic-validation.yml @@ -45,7 +45,12 @@ jobs: uses: ./.github/workflows/slow-checks.yml needs: - restrict-to-default-branch - secrets: inherit # zizmor: ignore[secrets-inherit] - PTB cannot customize inherited secrets here yet; tracked in https://github.com/exasol/python-toolbox/issues/872. + (% if secrets.slow_checks %) + secrets: + (% for secret_name in secrets.slow_checks %) + (( secret_name )): ${{ secrets.(( secret_name )) }} + (% endfor %) + (% endif %) permissions: contents: read From 0a5e2053a7ce752ac8c021b46f78d225cd08153c Mon Sep 17 00:00:00 2001 From: Ariel Schulz Date: Thu, 18 Jun 2026 14:23:42 +0200 Subject: [PATCH 03/13] Switch to supporting multiple customizations --- .github/workflows/ci.yml | 3 +- .github/workflows/merge-gate.yml | 1 - exasol/toolbox/config.py | 47 +++++++++++++++---- .../toolbox/templates/github/workflows/cd.yml | 7 ++- .../toolbox/templates/github/workflows/ci.yml | 7 ++- .../templates/github/workflows/merge-gate.yml | 7 ++- test/unit/config_test.py | 11 +++++ 7 files changed, 69 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e80c736c0..0a34a268b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,8 @@ jobs: merge-gate: name: Merge Gate uses: ./.github/workflows/merge-gate.yml - secrets: inherit # zizmor: ignore[secrets-inherit] - PTB cannot customize inherited secrets here yet; tracked in https://github.com/exasol/python-toolbox/issues/872. + secrets: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} permissions: contents: read diff --git a/.github/workflows/merge-gate.yml b/.github/workflows/merge-gate.yml index aa3e3e29b..408033e39 100644 --- a/.github/workflows/merge-gate.yml +++ b/.github/workflows/merge-gate.yml @@ -52,7 +52,6 @@ jobs: merge-gate-extension: uses: ./.github/workflows/merge-gate-extension.yml - secrets: inherit # zizmor: ignore[secrets-inherit] - PTB cannot customize inherited secrets here yet; tracked in https://github.com/exasol/python-toolbox/issues/872. permissions: contents: read diff --git a/exasol/toolbox/config.py b/exasol/toolbox/config.py index fccfad0a3..3af13de62 100644 --- a/exasol/toolbox/config.py +++ b/exasol/toolbox/config.py @@ -137,6 +137,35 @@ def check_minimum_version(cls, v: str, info: ValidationInfo) -> str: return v +class CustomWorkflowSecrets(BaseModel): + cd_extension: tuple[str, ...] = Field( + default=(), + description=""" + This tuple defines the string names of secrets needed to pass to the + cd-extension.yml. + """, + ) + slow_checks: tuple[str, ...] = Field( + default=(), + description=""" + This tuple defines the string names of secrets needed to pass to the + slow_checks.yml. + """, + ) + merge_gate_extension: tuple[str, ...] = Field( + default=(), + description=""" + This tuple defines the string names of secrets needed to pass to the + merge-gate-extension.yml. + """, + ) + + def get_secrets_dict(self) -> dict[str, tuple[str, ...]]: + secrets = self.model_dump(exclude_computed_fields=True) + secrets["merge_gate"] = self.merge_gate_extension + self.slow_checks + return secrets + + class BaseConfig(BaseModel): """ Basic configuration for projects using the PTB @@ -207,11 +236,11 @@ class BaseConfig(BaseModel): are supported. """, ) - secrets_slow_checks: tuple[str, ...] = Field( - default=(), - description="""This tuple defines the string names of secrets needed to pass - to the slow-checks.yml. - """ + custom_workflow_secrets: CustomWorkflowSecrets = Field( + default=CustomWorkflowSecrets(), + description=""" + This object is used to set the secret arrays for custom workflows. + """, ) @computed_field # type: ignore[misc] @@ -330,11 +359,15 @@ def github_template_dict(self) -> dict[str, Any]: self.github_workflow_directory / "merge-gate-extension.yml" ) + secrets = self.custom_workflow_secrets.get_secrets_dict() + secrets["merge_gate"] += (self.sonar_token_name,) + return { "dependency_manager_version": self.dependency_manager.version, "minimum_python_version": self.minimum_python_version, "os_version": self.os_version, "python_versions": self.python_versions, + "secrets": secrets, "sonar_token_name": self.sonar_token_name, "workflow_header": f"{WORKFLOW_HEADER_PREFIX}{__version__}.", "workflow_extension": { @@ -342,10 +375,6 @@ def github_template_dict(self) -> dict[str, Any]: "fast_tests": fast_tests_extension.is_file(), "merge_gate": merge_gate_extension.is_file(), }, - "secrets": - { - "slow_checks": self.secrets_slow_checks, - } } @computed_field # type: ignore[misc] diff --git a/exasol/toolbox/templates/github/workflows/cd.yml b/exasol/toolbox/templates/github/workflows/cd.yml index 618063c3e..45b77545b 100644 --- a/exasol/toolbox/templates/github/workflows/cd.yml +++ b/exasol/toolbox/templates/github/workflows/cd.yml @@ -29,7 +29,12 @@ jobs: uses: ./.github/workflows/cd-extension.yml needs: - check-release-tag - secrets: inherit # zizmor: ignore[secrets-inherit] - PTB cannot customize inherited secrets here yet; tracked in https://github.com/exasol/python-toolbox/issues/872. + (% if secrets.cd_extension %) + secrets: + (% for secret_name in secrets.cd_extension %) + (( secret_name )): ${{ secrets.(( secret_name )) }} + (% endfor %) + (% endif %) permissions: contents: write (% endif %) diff --git a/exasol/toolbox/templates/github/workflows/ci.yml b/exasol/toolbox/templates/github/workflows/ci.yml index c79cb52d6..34c2424e2 100644 --- a/exasol/toolbox/templates/github/workflows/ci.yml +++ b/exasol/toolbox/templates/github/workflows/ci.yml @@ -9,7 +9,12 @@ jobs: merge-gate: name: Merge Gate uses: ./.github/workflows/merge-gate.yml - secrets: inherit # zizmor: ignore[secrets-inherit] - PTB cannot customize inherited secrets here yet; tracked in https://github.com/exasol/python-toolbox/issues/872. + (% if secrets.merge_gate %) + secrets: + (% for secret_name in secrets.merge_gate %) + (( secret_name )): ${{ secrets.(( secret_name )) }} + (% endfor %) + (% endif %) permissions: contents: read diff --git a/exasol/toolbox/templates/github/workflows/merge-gate.yml b/exasol/toolbox/templates/github/workflows/merge-gate.yml index cdd3f60f9..459ac5397 100644 --- a/exasol/toolbox/templates/github/workflows/merge-gate.yml +++ b/exasol/toolbox/templates/github/workflows/merge-gate.yml @@ -58,7 +58,12 @@ jobs: (% if workflow_extension.merge_gate %) merge-gate-extension: uses: ./.github/workflows/merge-gate-extension.yml - secrets: inherit # zizmor: ignore[secrets-inherit] - PTB cannot customize inherited secrets here yet; tracked in https://github.com/exasol/python-toolbox/issues/872. + (% if secrets.merge_gate_extension %) + secrets: + (% for secret_name in secrets.merge_gate_extension %) + (( secret_name )): ${{ secrets.(( secret_name )) }} + (% endfor %) + (% endif %) permissions: contents: read (% endif %) diff --git a/test/unit/config_test.py b/test/unit/config_test.py index 3115d0632..f30fae381 100644 --- a/test/unit/config_test.py +++ b/test/unit/config_test.py @@ -42,6 +42,11 @@ def test_works_as_defined(tmp_path, test_project_config_factory): assert config_dump == { "add_to_excluded_python_paths": (), "create_major_version_tags": False, + "custom_workflow_secrets": { + "cd_extension": (), + "merge_gate_extension": (), + "slow_checks": (), + }, "dependency_manager": {"name": "poetry", "version": "2.3.0"}, "documentation_path": root_path / "doc", "exasol_versions": ("8.29.13", "2025.1.8"), @@ -60,6 +65,12 @@ def test_works_as_defined(tmp_path, test_project_config_factory): "3.13", "3.14", ), + "secrets": { + "cd_extension": (), + "merge_gate": ("SONAR_TOKEN",), + "merge_gate_extension": (), + "slow_checks": (), + }, "workflow_extension": { "cd": False, "fast_tests": False, From c7cf8dbf7ba6d9245fd7670d7ecd760a3dadaa16 Mon Sep 17 00:00:00 2001 From: Ariel Schulz Date: Thu, 18 Jun 2026 14:24:56 +0200 Subject: [PATCH 04/13] Switch example as secrets allowed --- doc/user_guide/troubleshooting/handle_zizmor_findings.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/user_guide/troubleshooting/handle_zizmor_findings.rst b/doc/user_guide/troubleshooting/handle_zizmor_findings.rst index 69916e4fe..4a3efb191 100644 --- a/doc/user_guide/troubleshooting/handle_zizmor_findings.rst +++ b/doc/user_guide/troubleshooting/handle_zizmor_findings.rst @@ -32,7 +32,7 @@ A typical line-level ignore looks like this: .. code-block:: yaml - secrets: inherit # zizmor: ignore[secrets-inherit] - PTB cannot customize inherited secrets here yet. + secrets: inherit # zizmor: ignore[github-env] - This shared action is used by many workflows, and downstream steps need `poetry` on PATH; we do not have a safer replacement yet. Use configuration rules in ``.zizmor.yml`` only when the finding is genuinely project-wide. If you add a temporary rule while working through a batch of From d6970d0d355b55436f35fec02dd10dc1ec2c15cb Mon Sep 17 00:00:00 2001 From: Ariel Schulz Date: Thu, 18 Jun 2026 14:33:03 +0200 Subject: [PATCH 05/13] Add unit test for CustomWorkflowSecrets --- test/unit/config_test.py | 55 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/test/unit/config_test.py b/test/unit/config_test.py index f30fae381..df401743e 100644 --- a/test/unit/config_test.py +++ b/test/unit/config_test.py @@ -10,6 +10,7 @@ from exasol.toolbox.config import ( DEFAULT_EXCLUDED_PATHS, BaseConfig, + CustomWorkflowSecrets, DependencyManager, minimum_declared_version, valid_version_string, @@ -143,6 +144,60 @@ def sonar_token_name(self) -> str: return "SONAR_ANOTHER_TOKEN" +class TestCustomWorkflowSecrets: + @staticmethod + def test_default(): + custom_workflow_secrets = CustomWorkflowSecrets() + secrets = custom_workflow_secrets.get_secrets_dict() + + assert secrets == { + "cd_extension": (), + "merge_gate": (), + "merge_gate_extension": (), + "slow_checks": (), + } + + @staticmethod + def test_single_override(): + cd_ext_secret = "CD_SECRET" + + custom_workflow_secrets = CustomWorkflowSecrets( + cd_extension=(cd_ext_secret,), + ) + secrets = custom_workflow_secrets.get_secrets_dict() + + assert secrets == { + "cd_extension": (cd_ext_secret,), + "merge_gate": (), + "merge_gate_extension": (), + "slow_checks": (), + } + + @staticmethod + def test_multiple_overrides(): + cd_ext_secret = "CD_SECRET" + merge_gate_ext_secret = "MERGE_GATE_SECRET" + slow_checks_secret = "SLOW_CHECKS_SECRET" + + custom_workflow_secrets = CustomWorkflowSecrets( + cd_extension=(cd_ext_secret,), + merge_gate_extension=(merge_gate_ext_secret, merge_gate_ext_secret), + slow_checks=(slow_checks_secret,), + ) + secrets = custom_workflow_secrets.get_secrets_dict() + + assert secrets == { + "cd_extension": (cd_ext_secret,), + "merge_gate": ( + merge_gate_ext_secret, + merge_gate_ext_secret, + slow_checks_secret, + ), + "merge_gate_extension": (merge_gate_ext_secret, merge_gate_ext_secret), + "slow_checks": (slow_checks_secret,), + } + + def test_expansion_validation_fails_for_invalid_version(): with pytest.raises(ValueError): BaseConfigExpansion(python_versions=("1.f.0",)) From 84550b41e8deb19d96efc9b68ca5238a8ef24900 Mon Sep 17 00:00:00 2001 From: Ariel Schulz Date: Thu, 18 Jun 2026 14:34:45 +0200 Subject: [PATCH 06/13] Add comment --- exasol/toolbox/config.py | 1 + 1 file changed, 1 insertion(+) diff --git a/exasol/toolbox/config.py b/exasol/toolbox/config.py index 3af13de62..2e708a107 100644 --- a/exasol/toolbox/config.py +++ b/exasol/toolbox/config.py @@ -360,6 +360,7 @@ def github_template_dict(self) -> dict[str, Any]: ) secrets = self.custom_workflow_secrets.get_secrets_dict() + # merge-gate.yml also calls report.yml and needs Sonar token secrets["merge_gate"] += (self.sonar_token_name,) return { From f595f3e13c7961e86658d817e4af74c6dfd539de Mon Sep 17 00:00:00 2001 From: Ariel Schulz Date: Thu, 18 Jun 2026 14:43:52 +0200 Subject: [PATCH 07/13] Update tests to include checking when has the jinja secrets --- test/unit/config_test.py | 6 +- test/unit/util/workflows/render_yaml_test.py | 95 +++++++++++++++++++- 2 files changed, 96 insertions(+), 5 deletions(-) diff --git a/test/unit/config_test.py b/test/unit/config_test.py index df401743e..4b7be1c3f 100644 --- a/test/unit/config_test.py +++ b/test/unit/config_test.py @@ -146,7 +146,7 @@ def sonar_token_name(self) -> str: class TestCustomWorkflowSecrets: @staticmethod - def test_default(): + def test_get_secrets_dict_defaults(): custom_workflow_secrets = CustomWorkflowSecrets() secrets = custom_workflow_secrets.get_secrets_dict() @@ -158,7 +158,7 @@ def test_default(): } @staticmethod - def test_single_override(): + def test_get_secrets_dict_with_cd_extension_override(): cd_ext_secret = "CD_SECRET" custom_workflow_secrets = CustomWorkflowSecrets( @@ -174,7 +174,7 @@ def test_single_override(): } @staticmethod - def test_multiple_overrides(): + def test_get_secrets_dict_merges_merge_gate_extension_and_slow_checks(): cd_ext_secret = "CD_SECRET" merge_gate_ext_secret = "MERGE_GATE_SECRET" slow_checks_secret = "SLOW_CHECKS_SECRET" diff --git a/test/unit/util/workflows/render_yaml_test.py b/test/unit/util/workflows/render_yaml_test.py index eed3331ff..a48ff4968 100644 --- a/test/unit/util/workflows/render_yaml_test.py +++ b/test/unit/util/workflows/render_yaml_test.py @@ -252,7 +252,9 @@ def test_updates_jinja_variables(test_yml, yaml_renderer): assert yaml_renderer.get_as_string(yaml_dict) == cleandoc(expected_yaml) @staticmethod - def test_does_not_add_jinja_block(test_yml, yaml_renderer, project_config): + def test_omits_block_when_extension_is_missing( + test_yml, yaml_renderer, project_config + ): input_yaml = """ jobs: run-unit-tests: @@ -304,7 +306,9 @@ def test_does_not_add_jinja_block(test_yml, yaml_renderer, project_config): assert yaml_renderer.get_as_string(yaml_dict) == cleandoc(expected_yaml) @staticmethod - def test_adds_jinja_block(test_yml, project_config): + def test_includes_if_block_when_extension_is_present( + test_yml, project_config + ): input_yaml = """ jobs: run-unit-tests: @@ -368,6 +372,93 @@ def test_adds_jinja_block(test_yml, project_config): assert yaml_renderer.get_as_string(yaml_dict) == cleandoc(expected_yaml) + @staticmethod + def test_includes_extension_with_multiple_secrets( + test_yml, project_config + ): + input_yaml = """ + jobs: + run-unit-tests: + name: Unit Tests (Python-${{ matrix.python-versions }}) + runs-on: "(( os_version ))" + permissions: + contents: read + strategy: + fail-fast: false + matrix: + python-versions: (( python_versions | tojson )) + + steps: + - name: Check out Repository + id: check-out-repository + uses: actions/checkout@v6 + + (% if workflow_extension.merge_gate %) + merge-gate-extension: + uses: ./.github/workflows/merge-gate-extension.yml + (% if secrets.merge_gate_extension %) + secrets: + (% for secret_name in secrets.merge_gate_extension %) + (( secret_name )): ${{ secrets.(( secret_name )) }} + (% endfor %) + (% endif %) + permissions: + contents: read + (% endif %) + + """ + expected_yaml = """ + jobs: + run-unit-tests: + name: Unit Tests (Python-${{ matrix.python-versions }}) + runs-on: "ubuntu-24.04" + permissions: + contents: read + strategy: + fail-fast: false + matrix: + python-versions: ["3.10", "3.11", "3.12", "3.13", "3.14"] + + steps: + - name: Check out Repository + id: check-out-repository + uses: actions/checkout@v6 + + merge-gate-extension: + uses: ./.github/workflows/merge-gate-extension.yml + secrets: + MERGE_GATE_SECRET: ${{ secrets.MERGE_GATE_SECRET }} + ANOTHER_SECRET: ${{ secrets.ANOTHER_SECRET }} + permissions: + contents: read + + """ + workflow_directory = project_config.github_workflow_directory + workflow_directory.mkdir(parents=True) + (workflow_directory / "merge-gate-extension.yml").touch() + + custom_workflow_secrets = project_config.custom_workflow_secrets.model_copy( + update={ + "merge_gate_extension": ( + "MERGE_GATE_SECRET", + "ANOTHER_SECRET", + ) + } + ) + updated_project_config = project_config.model_copy( + update={"custom_workflow_secrets": custom_workflow_secrets} + ) + yaml_renderer = YamlRenderer( + github_template_dict=updated_project_config.github_template_dict, + file_path=test_yml, + ) + + content = cleandoc(input_yaml) + test_yml.write_text(content) + + yaml_dict = yaml_renderer.get_yaml_dict() + assert yaml_renderer.get_as_string(yaml_dict) == cleandoc(expected_yaml) + @staticmethod def test_jinja_variable_unknown(test_yml, yaml_renderer): input_yaml = """ From 6c1a4f14fcfa1f6cbd44154100db796dcc01be49 Mon Sep 17 00:00:00 2001 From: Ariel Schulz Date: Thu, 18 Jun 2026 14:55:34 +0200 Subject: [PATCH 08/13] Add documentation for new feature --- doc/api/custom_workflow_secrets.rst | 12 ++++++++++++ doc/api/index.rst | 1 + .../features/github_workflows/workflow_variables.rst | 9 +++++++++ 3 files changed, 22 insertions(+) create mode 100644 doc/api/custom_workflow_secrets.rst diff --git a/doc/api/custom_workflow_secrets.rst b/doc/api/custom_workflow_secrets.rst new file mode 100644 index 000000000..5d58289d7 --- /dev/null +++ b/doc/api/custom_workflow_secrets.rst @@ -0,0 +1,12 @@ +.. _custom_workflow_secrets: + +CustomWorkflowSecrets +===================== + +.. currentmodule:: exasol.toolbox.config + +.. autoclass:: CustomWorkflowSecrets + :members: + :undoc-members: + :show-inheritance: + :member-order: bysource diff --git a/doc/api/index.rst b/doc/api/index.rst index 8ad43c961..90e79ce62 100644 --- a/doc/api/index.rst +++ b/doc/api/index.rst @@ -7,5 +7,6 @@ :maxdepth: 2 base_config + custom_workflow_secrets workflow_exceptions workflow_patcher_config diff --git a/doc/user_guide/features/github_workflows/workflow_variables.rst b/doc/user_guide/features/github_workflows/workflow_variables.rst index b1ee9ba5b..182bbb593 100644 --- a/doc/user_guide/features/github_workflows/workflow_variables.rst +++ b/doc/user_guide/features/github_workflows/workflow_variables.rst @@ -19,6 +19,15 @@ standardized baseline that can be overridden in individual projects. :start-at: github_template_dict :end-before: @computed_field +Custom Workflow Secrets +^^^^^^^^^^^^^^^^^^^^^^^ + +If your project needs to pass secrets into project-controlled workflows, configure +the ``custom_workflow_secrets`` field on :class:`exasol.toolbox.config.BaseConfig`. +That field uses :class:`exasol.toolbox.config.CustomWorkflowSecrets` and lets you +define separate secret tuples for specific workflows. See the API reference for +:class:`exasol.toolbox.config.CustomWorkflowSecrets` for the exact structure. + .. _workflow_matrix: From e325ba6e3bf38fdc5e309f988298790f833624fe Mon Sep 17 00:00:00 2001 From: Ariel Schulz Date: Thu, 18 Jun 2026 14:56:03 +0200 Subject: [PATCH 09/13] Alphabetize by name --- exasol/toolbox/config.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/exasol/toolbox/config.py b/exasol/toolbox/config.py index 2e708a107..822f1b350 100644 --- a/exasol/toolbox/config.py +++ b/exasol/toolbox/config.py @@ -145,18 +145,18 @@ class CustomWorkflowSecrets(BaseModel): cd-extension.yml. """, ) - slow_checks: tuple[str, ...] = Field( + merge_gate_extension: tuple[str, ...] = Field( default=(), description=""" This tuple defines the string names of secrets needed to pass to the - slow_checks.yml. + merge-gate-extension.yml. """, ) - merge_gate_extension: tuple[str, ...] = Field( + slow_checks: tuple[str, ...] = Field( default=(), description=""" This tuple defines the string names of secrets needed to pass to the - merge-gate-extension.yml. + slow_checks.yml. """, ) From 178d2bcd276d46ede7837a2e9bce2d9b939e3005 Mon Sep 17 00:00:00 2001 From: Ariel Schulz Date: Thu, 18 Jun 2026 15:09:16 +0200 Subject: [PATCH 10/13] Add missing needed block --- .github/workflows/merge-gate.yml | 3 +++ .../toolbox/templates/github/workflows/merge-gate.yml | 11 +++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/merge-gate.yml b/.github/workflows/merge-gate.yml index 408033e39..b77cc4bab 100644 --- a/.github/workflows/merge-gate.yml +++ b/.github/workflows/merge-gate.yml @@ -4,6 +4,9 @@ name: Merge-Gate on: workflow_call: + secrets: + SONAR_TOKEN: + required: true jobs: run-fast-checks: diff --git a/exasol/toolbox/templates/github/workflows/merge-gate.yml b/exasol/toolbox/templates/github/workflows/merge-gate.yml index 459ac5397..ba08e8046 100644 --- a/exasol/toolbox/templates/github/workflows/merge-gate.yml +++ b/exasol/toolbox/templates/github/workflows/merge-gate.yml @@ -3,6 +3,13 @@ name: Merge-Gate on: workflow_call: + (% if secrets.merge_gate %) + secrets: + (% for secret_name in secrets.merge_gate %) + (( secret_name )): + required: true + (% endfor %) + (% endif %) jobs: run-fast-checks: @@ -80,9 +87,9 @@ jobs: - run-fast-checks - run-fast-tests - run-slow-checks - (% if workflow_extension.merge_gate %) + (% if workflow_extension.merge_gate %) - merge-gate-extension - (% endif %) + (% endif %) # To prevent accidentally merges, this step is required. For more details # see: https://github.com/exasol/python-toolbox/issues/563 steps: From abe51a89732872b4c275ac328a93fe52ec847eba Mon Sep 17 00:00:00 2001 From: Ariel Schulz Date: Thu, 18 Jun 2026 15:13:58 +0200 Subject: [PATCH 11/13] Update documentation --- .../github_workflows/workflow_variables.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/doc/user_guide/features/github_workflows/workflow_variables.rst b/doc/user_guide/features/github_workflows/workflow_variables.rst index 182bbb593..f509cc284 100644 --- a/doc/user_guide/features/github_workflows/workflow_variables.rst +++ b/doc/user_guide/features/github_workflows/workflow_variables.rst @@ -28,6 +28,24 @@ That field uses :class:`exasol.toolbox.config.CustomWorkflowSecrets` and lets yo define separate secret tuples for specific workflows. See the API reference for :class:`exasol.toolbox.config.CustomWorkflowSecrets` for the exact structure. +Those custom secrets must be declared at the top of the reusable workflow file, under +``on.workflow_call`` and before ``jobs``. The generated workflows rely on that shape +when they call the reusable workflow with ``secrets:``. + +For example, ``slow-checks.yml`` keeps its reusable workflow header at the top of the +file: + +.. code-block:: yaml + + name: Slow-Checks + + on: + workflow_call: + secrets: + EXAMPLE_SECRET: + required: true + + .. _workflow_matrix: From b807b23c3a0f370fae11dc98bbaa5e3c47d8698e Mon Sep 17 00:00:00 2001 From: Ariel Schulz Date: Thu, 18 Jun 2026 15:15:17 +0200 Subject: [PATCH 12/13] Add changelog entry --- doc/changes/unreleased.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/changes/unreleased.md b/doc/changes/unreleased.md index 4fcaebf47..ea818553f 100644 --- a/doc/changes/unreleased.md +++ b/doc/changes/unreleased.md @@ -12,6 +12,7 @@ so ITDE-related test flows use the configured Exasol baseline and unit-test help ## Feature * #878: Added Nox session `workflow:audit` which uses `zizmor` and added it in `checks.yml` +* #872: Added `custom_workflow_secrets` to `BaseConfig` so that tuples of secrets can be defined for custom workflows, like `slow-checks.yml` ## Refactoring From 7487e6b2c34118476d7c0c8e3f28d03eeda82fed Mon Sep 17 00:00:00 2001 From: Ariel Schulz Date: Thu, 18 Jun 2026 15:15:43 +0200 Subject: [PATCH 13/13] Run format:fix --- test/unit/util/workflows/render_yaml_test.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/test/unit/util/workflows/render_yaml_test.py b/test/unit/util/workflows/render_yaml_test.py index a48ff4968..2ed60e596 100644 --- a/test/unit/util/workflows/render_yaml_test.py +++ b/test/unit/util/workflows/render_yaml_test.py @@ -306,9 +306,7 @@ def test_omits_block_when_extension_is_missing( assert yaml_renderer.get_as_string(yaml_dict) == cleandoc(expected_yaml) @staticmethod - def test_includes_if_block_when_extension_is_present( - test_yml, project_config - ): + def test_includes_if_block_when_extension_is_present(test_yml, project_config): input_yaml = """ jobs: run-unit-tests: @@ -373,9 +371,7 @@ def test_includes_if_block_when_extension_is_present( assert yaml_renderer.get_as_string(yaml_dict) == cleandoc(expected_yaml) @staticmethod - def test_includes_extension_with_multiple_secrets( - test_yml, project_config - ): + def test_includes_extension_with_multiple_secrets(test_yml, project_config): input_yaml = """ jobs: run-unit-tests: