Skip to content

Convert boolean safe output fields to templatable bools - #17653

Merged
pelikhan merged 6 commits into
mainfrom
copilot/convert-boolean-fields-to-templatable-bools
Feb 22, 2026
Merged

Convert boolean safe output fields to templatable bools#17653
pelikhan merged 6 commits into
mainfrom
copilot/convert-boolean-fields-to-templatable-bools

Conversation

CopilotAI commented Feb 22, 2026

Copy link
Copy Markdown
Contributor
  • Convert non-permission-affecting boolean fields to *string templatable bools
  • Keep CreateDiscussionsConfig.FallbackToIssue as *bool (Go side)
  • Revert fallbackToIssue in create_discussion.cjs to original config.fallback_to_issue !== false pattern
  • Extract buildTemplatableBoolEnvVar helper into templatables.go and refactor all strings.HasPrefix("${{") call sites in add_comment.go, create_issue.go, create_discussion.go, create_pull_request.go, notify_comment.go
Original prompt

Create a plan to convert the Boolean safe output fields into templetable bools.

All Boolean fields can be converted at the one condition that they are not used to influence the permissions in the .lock.yml files.

For example, add_comment.discussions, create/pull-request.fallaback_as_issue are used to compute oermissions. Do not convert.

See how create-pull-request.draft was converted for the pattern and the existing JavaScript helpers.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot do not convert CreateDiscussionsConfig.FallbackToIssue

- CloseOlderIssues/Group/Footer in CreateIssuesConfig: bool/*bool → *string
- HideOlderComments in AddCommentsConfig: bool → *string
- CloseOlderDiscussions/FallbackToIssue/Footer in CreateDiscussionsConfig: bool/*bool → *string
- AllowEmpty/AutoMerge/Footer in CreatePullRequestsConfig: bool/*bool → *string
- UnassignFirst in AssignToUserConfig: bool → *string
- ReportAsIssue in NoOpConfig: bool → *string
- Footer in UpdateIssuesConfig/UpdatePullRequestsConfig/UpdateDiscussionsConfig/UpdateReleaseConfig/ReplyToPRReviewCommentConfig: *bool → *string
- Add FieldParsingTemplatableBool mode to update_entity_helpers.go
- Add getEffectiveFooterForTemplatable helper (replaces getEffectiveFooter)
- Update handler registry to use AddTemplatableBool
- Update build job functions to emit expressions or quoted strings
- Update all JS handlers to use parseBoolTemplatable from templatable.cjs
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
CopilotAI changed the title [WIP] Convert Boolean safe output fields to templatable boolsConvert boolean safe output fields to templatable boolsFeb 22, 2026
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

CopilotAI commented Feb 22, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot do not convert CreateDiscussionsConfig.FallbackToIssue

Reverted in 2f346c7FallbackToIssue is kept as *bool.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw (http block)
  • https://api.github.com/repos/actions/ai-inference/git/ref/tags/v1
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha ithub/workflows on rkflow/js/**/*.json /../../.prettiergit erignore -nilfunc bash --no�� tags/4dc6199c7b1a012772edbd06daecab0f50c9053c -tests /home/REDACTED/work/gh-aw/node_modules/.bin/sh (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/11bd71901bbe5b1630ceea73d27597364c9af683
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/11bd71901bbe5b1630ceea73d27597364c9af683 --jq .object.sha w/js/**/*.json&#39; --ignore-path ../../../.prettierignore (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha .js&#39; --ignore-path .prettierignoremote.origin.url 494091/b134/vet.cfg ode (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v4 --jq .object.sha ithub/workflows /tmp/go-build409494091/b111/vet.cfg repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -c=4 -nolocalimports erignore /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linurev-parse -uns�� te &#39;../../../**/*.json&#39; &#39;!../../../pkg/workflow/js/**/*.json&#39; --remote.origin.url /tmp/go-build409494091/b173/vet.cfg ker/cli-plugins/docker-buildx (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v4 --jq .object.sha -unreachable=false /tmp/go-build409494091/b117/vet.cfg p/bin/sh (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v4 --jq .object.sha k/gh-aw/gh-aw/.github/workflows x_amd64/vet /usr/bin/git h ../../../.pretgit (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha ../pkg/workflow/js/**/*.json&#39; --ignore-path ../../../.prettierignore cfg 64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha ithub/workflows **/*.cjs /opt/hostedtoolcache/node/24.13.0/x64/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/n--show-toplevel **/*.json --ignore-path DiscussionsEnablsource &#39;/home/REDACTED/work/gh-aw/gh-aw/actions/setup/sh/sanitize_path.sh&#39; &#39;/usr/bin:/usr/local/bin&#39; &amp;&amp; echo &#34;$PATH&#34; sh -c &#34;prettier&#34; --write &#39;../../../**/*.json&#39; &#39;!../../../pkg/workflow/js/**/*.json&#39; --ignore-path ../.sed (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha /repos/actions/setup-go/git/ref/tags/v6 --jq /usr/bin/gh w/js/**/*.json&#39; git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha w/js/**/*.json&#39; --ignore-path (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v7
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v7 --jq .object.sha (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v8
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha ithub/workflows /tmp/go-build409494091/b104/vet.cfg repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha ithub/workflows /tmp/go-build409494091/b063/vet.cfg sh (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha /home/REDACTED/work/gh-aw/gh-aw/.github/workflows config er: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabl--show-toplevel remote.origin.urgit (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/4dc6199c7b1a012772edbd06daecab0f50c9053c
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/4dc6199c7b1a012772edbd06daecab0f50c9053c --jq .object.sha (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha -unreachable=false /tmp/go-build409494091/b079/vet.-w me: String!) { repository(owne-buildmode=exe (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v5 --jq .object.sha h ../../../.pret.prettierignore (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v6 --jq .object.sha ignore-path ../../../.prettierignore (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v6 --jq .object.sha (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v6 --jq .object.sha w/js/**/*.json&#39; --ignore-path (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha ithub/workflows /tmp/go-build409494091/b048/vet.cfg ache/node/24.13.0/x64/bin/sh -c=4 -nolocalimports erignore /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linurev-parse -uns�� ithub/workflows /tmp/go-build409494091/b200/vet.cfg bash (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v6 --jq .object.sha ignore-path ../../../.prettierignore (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v6 --jq .object.sha (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v6 --jq .object.sha json&#39; --ignore-p-f cfg 64/pkg/tool/linu-f (http block)
  • https://api.github.com/repos/anchore/sbom-action/git/ref/tags/v0
    • Triggering command: /usr/bin/gh gh api /repos/anchore/sbom-action/git/ref/tags/v0 --jq .object.sha (http block)
  • https://api.github.com/repos/docker/build-push-action/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/docker/build-push-action/git/ref/tags/v6 --jq .object.sha (http block)
  • https://api.github.com/repos/docker/login-action/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/docker/login-action/git/ref/tags/v3 --jq .object.sha (http block)
  • https://api.github.com/repos/docker/metadata-action/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/docker/metadata-action/git/ref/tags/v5 --jq .object.sha (http block)
  • https://api.github.com/repos/docker/setup-buildx-action/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/docker/setup-buildx-action/git/ref/tags/v3 --jq .object.sha ./cmd/gh-aw (http block)
    • Triggering command: /usr/bin/gh gh api /repos/docker/setup-buildx-action/git/ref/tags/v3 --jq .object.sha ify@v1.11.1/asse-f ify@v1.11.1/asseowner=github 64/pkg/tool/linu-f (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/a70c5eada06553e3510ac27f2c3bda9d3705bccb
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/a70c5eada06553e3510ac27f2c3bda9d3705bccb --jq .object.sha (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha th .prettierigno-f cfg _modules/.bin/no-f (http block)
  • https://api.github.com/repos/githubnext/agentics/git/ref/tags/
    • Triggering command: /usr/bin/gh gh api /repos/githubnext/agentics/git/ref/tags/# --jq .object.sha h ../../../.prettierignore (http block)
  • https://api.github.com/repos/nonexistent/action/git/ref/tags/v999.999.999
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha th .prettierignore (http block)

If you need me to access, download, or install something from one of these locations, you can either:

const fallbackToIssue = config.fallback_to_issue !== false; // Default to true
const closeOlderDiscussions = config.close_older_discussions === true || config.close_older_discussions === "true";
const includeFooter = config.footer !== false; // Default to true (include footer)
const fallbackToIssue = parseBoolTemplatable(config.fallback_to_issue, true);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot revert fallbackToIssue

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted in 82c3a58fallbackToIssue now uses config.fallback_to_issue !== false again.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Comment threadpkg/workflow/add_comment.go Outdated
customEnvVars = append(customEnvVars, " GH_AW_HIDE_OLDER_COMMENTS: \"true\"\n")
if data.SafeOutputs.AddComments.HideOlderComments != nil {
hoc := *data.SafeOutputs.AddComments.HideOlderComments
if strings.HasPrefix(hoc, "${{") {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot move this check to a helper function and refactor

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 49471ab — added buildTemplatableBoolEnvVar(envVarName string, value *string) []string to templatables.go and replaced all inline strings.HasPrefix("${{") blocks in add_comment.go, create_issue.go, create_discussion.go, create_pull_request.go, and notify_comment.go with calls to this helper.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@pelikhan
pelikhan marked this pull request as ready for review February 22, 2026 06:13
CopilotAI review requested due to automatic review settings February 22, 2026 06:13

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Converts several “safe” boolean safe-output config fields from Go bool/*bool to templatable *string values, enabling GitHub Actions expressions (e.g. ${{ inputs.flag }}) to control runtime behavior while keeping permission-affecting booleans as real booleans.

Changes:

  • Introduced a templatable-bool parsing mode for update-* entities and refactored multiple configs to use *string + templatable parsing.
  • Added a shared buildTemplatableBoolEnvVar helper and migrated job env-var emission to support expression values.
  • Updated JS handlers to parse templatable booleans consistently via parseBoolTemplatable, and refreshed affected tests/lock output.

Reviewed changes

Copilot reviewed 34 out of 34 changed files in this pull request and generated 1 comment.

Show a summary per file
FileDescription
pkg/workflow/update_release.goSwitch footer to templatable bool parsing for update-release.
pkg/workflow/update_pull_request.goSwitch footer to templatable bool parsing for update-pull-request.
pkg/workflow/update_issue.goSwitch footer to templatable bool parsing for update-issue.
pkg/workflow/update_entity_helpers.goAdd FieldParsingTemplatableBool mode, string parsing helper, and spec plumbing.
pkg/workflow/update_discussion.goSwitch footer to templatable bool parsing for update-discussion.
pkg/workflow/templatables.goAdd buildTemplatableBoolEnvVar helper for YAML env emission of templatable bools.
pkg/workflow/safe_outputs_footer_test.goUpdate footer-related assertions for *string templatable bools.
pkg/workflow/safe_outputs_config_generation_helpers.goUpdate PR config generator signature to accept templatable bools (now *string).
pkg/workflow/safe_outputs_config_generation.goUpdate generation logic for templatable group field.
pkg/workflow/safe_outputs_config.goChange noop default report-as-issue representation to templatable *string.
pkg/workflow/reply_to_pr_review_comment.goParse reply footer as templatable bool (*string).
pkg/workflow/notify_comment.goEmit noop report-as-issue as templatable env var.
pkg/workflow/noop_test.goUpdate noop tests for report-as-issue now being *string.
pkg/workflow/noop.goChange noop report-as-issue to templatable *string with preprocessing.
pkg/workflow/create_pull_request.goConvert allow-empty/auto-merge/footer to templatable bools; use shared env-var helper.
pkg/workflow/create_issue.goConvert close-older-issues/group/footer to templatable bools; preprocess before unmarshal.
pkg/workflow/create_discussion.goConvert close-older-discussions/footer to templatable bools; preprocess before unmarshal.
pkg/workflow/compiler_safe_outputs_config_test.goUpdate config builder tests for templatable boolean fields.
pkg/workflow/compiler_safe_outputs_config.goRoute templatable bool fields through AddTemplatableBool and new effective-footer helper.
pkg/workflow/compile_outputs_pr_test.goUpdate PR auto-merge test for templatable bool representation.
pkg/workflow/assign_to_user.goConvert unassign-first to templatable bool and preprocess before unmarshal.
pkg/workflow/add_comment_target_repo_test.goUpdate hide-older-comments tests for *string templatable bool.
pkg/workflow/add_comment.goConvert hide-older-comments to templatable bool; use shared env-var helper + preprocessing.
actions/setup/js/update_release.cjsUse parseBoolTemplatable for footer inclusion.
actions/setup/js/update_pull_request.cjsUse parseBoolTemplatable for footer inclusion.
actions/setup/js/update_issue.cjsUse parseBoolTemplatable for footer inclusion.
actions/setup/js/update_discussion.cjsUse parseBoolTemplatable for footer inclusion.
actions/setup/js/reply_to_pr_review_comment.cjsUse parseBoolTemplatable for footer inclusion.
actions/setup/js/create_pull_request.cjsUse parseBoolTemplatable for allow_empty/auto_merge/footer.
actions/setup/js/create_issue.cjsUse parseBoolTemplatable for group/close_older_issues/footer.
actions/setup/js/create_discussion.cjsUse parseBoolTemplatable for close_older_discussions/footer.
actions/setup/js/assign_to_user.cjsUse parseBoolTemplatable for unassign_first.
actions/setup/js/add_comment.cjsUse parseBoolTemplatable for hide_older_comments.
.github/workflows/weekly-safe-outputs-spec-review.lock.ymlRefresh handler-config JSON to include the new templatable fields.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 134 to 140
// Pass allow_empty flag to MCP server so it can skip patch generation
if allowEmpty {
if allowEmpty != nil && *allowEmpty == "true" {
config["allow_empty"] = true
}
// Pass auto_merge flag to enable auto-merge for the pull request
if autoMerge {
if autoMerge != nil && *autoMerge == "true" {
config["auto_merge"] = true

CopilotAIFeb 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generatePullRequestConfig only sets allow_empty/auto_merge when the value is the literal string "true". If the config uses a GitHub Actions expression (e.g. "${{ inputs.allow_empty }}"), the field is silently omitted from config.json, which means downstream runtime components that rely on config.json (e.g. patch generation / has_patch handling) will treat it as disabled even when the expression evaluates to true. Consider emitting the field for all non-nil values using the same templatable-bool encoding as handler config ("true"→true, "false"→false, expression→string) so runtime code can interpret it correctly.

See below for a potential fix:

	// Pass allow_empty flag to MCP server so it can skip patch generation.
// Use templatable-bool encoding: "true" -> true, "false" -> false, expression -> string.
if allowEmpty != nil {
switch *allowEmpty {
case "true":
config["allow_empty"] = true
case "false":
config["allow_empty"] = false
default:
config["allow_empty"] = *allowEmpty
}
}
// Pass auto_merge flag to enable auto-merge for the pull request.
// Use templatable-bool encoding: "true" -> true, "false" -> false, expression -> string.
if autoMerge != nil {
switch *autoMerge {
case "true":
config["auto_merge"] = true
case "false":
config["auto_merge"] = false
default:
config["auto_merge"] = *autoMerge
}

Copilot uses AI. Check for mistakes.
@pelikhan
pelikhan merged commit 29518ad into mainFeb 22, 2026
48 checks passed
@pelikhan
pelikhan deleted the copilot/convert-boolean-fields-to-templatable-bools branch February 22, 2026 06:31
github-actionsBot pushed a commit that referenced this pull request Feb 22, 2026
- Add `max-bot-mentions` global safe-outputs option (from #17689)
- Add Templatable Fields section covering expression support for
max, expires, max-bot-mentions, and boolean fields (from #17653, #17667)
- Update expires field description to note preferred string format
- Document expires-integer-to-string codemod in gh aw fix (from #17695)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
nomiscientist pushed a commit to nomiscientist/gh-aw that referenced this pull request Jun 4, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@pelikhan