Skip to content

Feature: parameterize safe-output boolean controls for reusable workflows #29172

@bbonafed

Description

@bbonafed

Problem

Several safe-output boolean controls are still compile-time-only or have schema/runtime inconsistencies. This limits reusable workflow_call workflows that want callers to select behavior at runtime without duplicating workflow files.

Examples of high-value boolean controls:

safe-outputs:
  report-incomplete:
    create-issue: ${{ inputs.create-incomplete-issue }}
  add-comment:
    hide-older-comments: ${{ inputs.hide-older-comments }}

Some safe-output booleans already use templatable bool handling internally, but schema validation does not consistently allow expression strings. Others remain plain bool fields in parser/config types.

Related context: #23724 confirmed that expression pass-through for frontmatter fields is desirable where it can be implemented safely. Existing merged follow-ups covered several timeout/version fields, but not these safe-output boolean controls.

Desired Behavior

Reusable workflows should be able to expose boolean inputs for safe-output behavior:

on:
  workflow_call:
    inputs:
      create-incomplete-issue:
        type: boolean
        default: true
      hide-older-comments:
        type: boolean
        default: true
---
safe-outputs:
  report-incomplete:
    create-issue: ${{ inputs.create-incomplete-issue }}
  add-comment:
    hide-older-comments: ${{ inputs.hide-older-comments }}

Literal values must continue to work:

safe-outputs:
  report-incomplete:
    create-issue: true
  add-comment:
    hide-older-comments: false

Proposed Scope

Start with the safe-output boolean controls that are commonly useful for reusable workflows:

  • safe-outputs.report-incomplete.create-issue
  • safe-outputs.missing-tool.create-issue
  • safe-outputs.missing-data.create-issue
  • safe-outputs.add-comment.hide-older-comments
  • Any existing templatable safe-output booleans whose Go parser supports expressions but whose JSON schema still only allows boolean

This intentionally avoids permission-shaping booleans where runtime parameterization would require compile-time job permission changes unless the implementation can preserve least privilege safely.

Implementation Plan

  1. Audit current boolean fields

    • Search for preprocessBoolFieldAsString, AddTemplatableBool, and plain bool / *bool safe-output config fields.
    • Identify fields where runtime templating is already supported in Go but blocked by schema.
    • Identify fields that need type changes from bool / *bool to the existing templatable string convention.
  2. Schema updates

    • Add or reuse a shared schema definition for templatable booleans: literal boolean or ${{ ... }} expression string.
    • Apply it to the scoped fields above.
    • Keep non-expression strings invalid.
  3. Parser/config updates

    • For fields currently represented as plain booleans, use the same pattern as other templatable safe-output booleans.
    • Preserve literal boolean behavior by converting literal true/false to JSON booleans in handler config where handlers already expect booleans.
    • Preserve default behavior when fields are omitted.
  4. Runtime/handler config

    • Ensure generated GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG can carry expression strings through to runtime without quoting in a way that prevents GitHub Actions evaluation.
    • Verify JavaScript handlers correctly interpret expression-evaluated values as booleans.
  5. Tests

    • Add parser and schema tests for literal booleans, expression booleans, omitted defaults, and invalid strings.
    • Add compiler tests for at least one issue-creation boolean and one comment-hiding boolean.
    • Add runtime handler tests if any handler currently assumes strict boolean types.
  6. Documentation

    • Update safe-output docs with a short reusable-workflow example.
    • Document which safe-output boolean controls support expressions.

Acceptance Criteria

  • The scoped safe-output boolean fields accept literal booleans and GitHub Actions expression strings.
  • Defaults remain unchanged when fields are omitted.
  • Non-expression strings are rejected with clear errors.
  • Generated handler config preserves expressions for runtime evaluation.
  • Existing literal safe-output configs remain backward compatible.
  • Tests and docs are updated.

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions