Skip to content

Comments

Convert boolean safe output fields to templatable bools#17653

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

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

Conversation

Copy link
Contributor

Copilot AI commented Feb 22, 2026

  • 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
Contributor

@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>
Copilot AI changed the title [WIP] Convert Boolean safe output fields to templatable bools Convert boolean safe output fields to templatable bools Feb 22, 2026
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 22, 2026

@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
Contributor

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
Contributor Author

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>
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
Contributor

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
Contributor Author

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
Copilot AI review requested due to automatic review settings February 22, 2026 06:13
Copy link
Contributor

Copilot AI left a comment

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
File Description
pkg/workflow/update_release.go Switch footer to templatable bool parsing for update-release.
pkg/workflow/update_pull_request.go Switch footer to templatable bool parsing for update-pull-request.
pkg/workflow/update_issue.go Switch footer to templatable bool parsing for update-issue.
pkg/workflow/update_entity_helpers.go Add FieldParsingTemplatableBool mode, string parsing helper, and spec plumbing.
pkg/workflow/update_discussion.go Switch footer to templatable bool parsing for update-discussion.
pkg/workflow/templatables.go Add buildTemplatableBoolEnvVar helper for YAML env emission of templatable bools.
pkg/workflow/safe_outputs_footer_test.go Update footer-related assertions for *string templatable bools.
pkg/workflow/safe_outputs_config_generation_helpers.go Update PR config generator signature to accept templatable bools (now *string).
pkg/workflow/safe_outputs_config_generation.go Update generation logic for templatable group field.
pkg/workflow/safe_outputs_config.go Change noop default report-as-issue representation to templatable *string.
pkg/workflow/reply_to_pr_review_comment.go Parse reply footer as templatable bool (*string).
pkg/workflow/notify_comment.go Emit noop report-as-issue as templatable env var.
pkg/workflow/noop_test.go Update noop tests for report-as-issue now being *string.
pkg/workflow/noop.go Change noop report-as-issue to templatable *string with preprocessing.
pkg/workflow/create_pull_request.go Convert allow-empty/auto-merge/footer to templatable bools; use shared env-var helper.
pkg/workflow/create_issue.go Convert close-older-issues/group/footer to templatable bools; preprocess before unmarshal.
pkg/workflow/create_discussion.go Convert close-older-discussions/footer to templatable bools; preprocess before unmarshal.
pkg/workflow/compiler_safe_outputs_config_test.go Update config builder tests for templatable boolean fields.
pkg/workflow/compiler_safe_outputs_config.go Route templatable bool fields through AddTemplatableBool and new effective-footer helper.
pkg/workflow/compile_outputs_pr_test.go Update PR auto-merge test for templatable bool representation.
pkg/workflow/assign_to_user.go Convert unassign-first to templatable bool and preprocess before unmarshal.
pkg/workflow/add_comment_target_repo_test.go Update hide-older-comments tests for *string templatable bool.
pkg/workflow/add_comment.go Convert hide-older-comments to templatable bool; use shared env-var helper + preprocessing.
actions/setup/js/update_release.cjs Use parseBoolTemplatable for footer inclusion.
actions/setup/js/update_pull_request.cjs Use parseBoolTemplatable for footer inclusion.
actions/setup/js/update_issue.cjs Use parseBoolTemplatable for footer inclusion.
actions/setup/js/update_discussion.cjs Use parseBoolTemplatable for footer inclusion.
actions/setup/js/reply_to_pr_review_comment.cjs Use parseBoolTemplatable for footer inclusion.
actions/setup/js/create_pull_request.cjs Use parseBoolTemplatable for allow_empty/auto_merge/footer.
actions/setup/js/create_issue.cjs Use parseBoolTemplatable for group/close_older_issues/footer.
actions/setup/js/create_discussion.cjs Use parseBoolTemplatable for close_older_discussions/footer.
actions/setup/js/assign_to_user.cjs Use parseBoolTemplatable for unassign_first.
actions/setup/js/add_comment.cjs Use parseBoolTemplatable for hide_older_comments.
.github/workflows/weekly-safe-outputs-spec-review.lock.yml Refresh 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
Copy link

Copilot AI Feb 22, 2026

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 main Feb 22, 2026
48 checks passed
@pelikhan pelikhan deleted the copilot/convert-boolean-fields-to-templatable-bools branch February 22, 2026 06:31
Sign up for free to 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.

2 participants