Conversation
6 tasks
…e-output parser duplication Addresses: https://github.com/github/gh-aw/issues (duplicate safe-output parser scaffold) - Add parseConfigScaffold[T any] generic helper to config_helpers.go - Refactor 8 handler parse*Config methods to use the scaffold - Add 7 focused unit tests in config_scaffold_helpers_test.go Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> Agent-Logs-Url: https://github.com/github/gh-aw/sessions/620a8f3e-6f77-4846-ac02-e47a24f52822
Copilot
AI
changed the title
[WIP] Refactor duplicated safe-output parser scaffold in pkg/workflow
refactor: extract generic Mar 25, 2026
parseConfigScaffold helper to eliminate safe-output parser duplication
Contributor
There was a problem hiding this comment.
Pull request overview
Refactors safe-output handler config parsing in pkg/workflow by extracting a shared generic scaffold helper to remove duplicated “key check → log → typed unmarshal → fallback/disable” logic and reduce drift risk across handlers.
Changes:
- Added generic
parseConfigScaffold[T any]helper inconfig_helpers.goto centralize common safe-output config parsing steps. - Refactored 8 safe-output handlers to delegate the common parsing scaffold to the new helper while keeping handler-specific preprocessing/postprocessing.
- Added unit tests for the scaffold helper covering key-absent, null/empty configs, valid configs, and error fallback/disable behavior.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/workflow/config_helpers.go | Adds the new generic parseConfigScaffold helper built on existing unmarshalConfig. |
| pkg/workflow/config_scaffold_helpers_test.go | Introduces focused unit tests validating the scaffold’s behavior across key scenarios. |
| pkg/workflow/add_labels.go | Switches to scaffold helper; preserves empty-config fallback and summary logging. |
| pkg/workflow/remove_labels.go | Switches to scaffold helper; preserves empty-config fallback and summary logging. |
| pkg/workflow/set_issue_type.go | Switches to scaffold helper; preserves disable-on-error behavior and summary logging. |
| pkg/workflow/assign_milestone.go | Switches to scaffold helper; preserves empty-config fallback and summary logging. |
| pkg/workflow/unassign_from_user.go | Switches to scaffold helper; preserves default-max fallback semantics and postprocessing. |
| pkg/workflow/assign_to_user.go | Uses scaffold helper after existing preprocessing; preserves default-max fallback and postprocessing. |
| pkg/workflow/assign_to_agent.go | Uses scaffold helper after existing preprocessing; preserves empty-config fallback + default max postprocessing. |
| pkg/workflow/mark_pull_request_as_ready_for_review.go | Uses scaffold helper then keeps existing target/filter postprocessing based on the raw config map. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
8+ safe-output handler config parsers in
pkg/workflowrepeated an identical 12–20 line scaffold: key existence check, entry log, typed unmarshal viaunmarshalConfig, error fallback, and return. Any behavioral change required touching every handler independently, creating drift risk.Changes
New generic helper:
parseConfigScaffold[T any](config_helpers.go)Encapsulates the four-step common pattern; caller supplies only the
onErrorcallback to express handler-specific fallback semantics:Refactored handlers (8 files)
Each handler's
parse*Configmethod is reduced to its unique logic — preprocessing, defaults, summary logging — with the scaffold delegated to the helper:add_labels.go,remove_labels.go— empty-config fallbackset_issue_type.go— disable-on-errorunassign_from_user.go— default-max fallback +Maxpost-processingassign_milestone.go— empty-config fallbackassign_to_user.go— templatable-field preprocessing + default-max fallbackassign_to_agent.go— templatable-field preprocessing + empty-config fallback + default maxmark_pull_request_as_ready_for_review.go— disable-on-error +ParseTargetConfig/ParseFilterConfigpost-processingHandlers with preprocessing retain an explicit key check before invoking the scaffold so field conversion happens prior to YAML unmarshaling.
Tests (
config_scaffold_helpers_test.go)7 focused unit tests covering: absent key, null value, valid config, empty-config fallback, disable-on-error, error propagation, and empty map.
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/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 GO111MODULE 64/bin/go git rev-�� --show-toplevel go /usr/bin/git -json GO111MODULE ache/go/1.25.0/x--show-toplevel git(http block)/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 sh /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel bash /usr/bin/git git(http block)https://api.github.com/orgs/test-owner/actions/secrets/usr/bin/gh gh api /orgs/test-owner/actions/secrets --jq .secrets[].name --check **/*.cjs 64/bin/go **/*.json --ignore-path ../../../.prettiprettier go env -json GO111MODULE /node GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/actions/ai-inference/git/ref/tags/v1/usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha --git-dir go /usr/bin/git -json GO111MODULE ode_modules/.bin--show-toplevel git conf�� --get remote.origin.url /usr/bin/git on' --ignore-patgit GO111MODULE 64/bin/go /usr/bin/git(http block)/usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha --show-toplevel git /usr/bin/git --show-toplevel go /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel go /usr/bin/git git(http block)https://api.github.com/repos/actions/checkout/git/ref/tags/v3/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha "prettier" --check 'scripts/**/*.js' --ignore-path .prettierigno-errorsas go 0/x64/bin/node tierignore GO111MODULE 64/bin/go 0/x64/bin/node -tes�� e: ${{ secrets.TOKEN }} -test.v=true /usr/bin/git -test.timeout=10git -test.run=^Test -test.short=true--show-toplevel git(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha /tmp/gh-aw/aw-master.patch git /usr/bin/git --git-dir go /usr/bin/git git rev-�� --show-toplevel /usr/bin/git /usr/bin/git --get-regexp ^remote\..*\.gh-rev-parse /usr/bin/git git(http block)https://api.github.com/repos/actions/checkout/git/ref/tags/v5/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha '**/*.ts' '**/*.json' --ignore-path ../../../.pr**/*.json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env .js' --ignore-path .prettierignore GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha inputs.version go /usr/bin/git th .prettierignogit GO111MODULE 64/bin/go git rev-�� --show-toplevel go /usr/bin/git -json GO111MODULE ache/go/1.25.0/x--show-toplevel git(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel kmIpjEVxgPIJbBLrkR/yyjxJESSHc3089fRgrZr/aHz0DOVUCYY4uw-nj1ib /usr/bin/git -json GO111MODULE g_.a git rev-�� --show-toplevel erignore /usr/bin/git GOPATH); \ if cogit GO111MODULE /opt/hostedtoolc--show-toplevel git(http block)https://api.github.com/repos/actions/checkout/git/ref/tags/v6/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha /tmp/go-build2999104003/b443/testutil.test -importcfg /usr/bin/git -s -w -buildmode=exe git rev-�� --show-toplevel -extld=gcc /opt/hostedtoolcache/node/24.14.0/x64/bin/node -json GO111MODULE 64/bin/go node(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha k/gh-aw/gh-aw/.github/workflows/blog-auditor.md -test.v=true /usr/bin/git -test.timeout=10git -test.run=^Test -test.short=true--show-toplevel git rese�� HEAD .github/workflows/test.md /usr/bin/git -json GO111MODULE 64/bin/go git(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha --show-toplevel 64/pkg/tool/linux_amd64/vet /usr/bin/git -json GO111MODULE k/gh-aw/gh-aw/ac--show-toplevel git rev-�� --show-toplevel go /usr/bin/git ck '**/*.cjs' '*git GO111MODULE .cfg git(http block)https://api.github.com/repos/actions/github-script/git/ref/tags/v8/usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha GoFiles,CompiledGOINSECURE **/*.ts 64/bin/go --ignore-path ../../../.pretti/opt/hostedtoolcache/node/24.14.0/x64/bin/npx 64/bin/go go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha --noprofile node(http block)/usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env h ../../../.pret.prettierignore GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/actions/setup-go/git/ref/tags/v4/usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha /tmp/go-build2999104003/b447/_pkg_.a -trimpath /usr/bin/git -p main -lang=go1.25 git add .github/workflows/test.md -dwarf=false /usr/bin/git go1.25.0 -c=4 -nolocalimports git(http block)/usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha --show-toplevel git /usr/bin/git --show-toplevel go /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel 64/pkg/tool/linurev-parse /usr/bin/git git(http block)https://api.github.com/repos/actions/setup-node/git/ref/tags/v4/usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha /tmp/TestHashConsistency_GoAndJavaScript3945506491/001/test-frontmatter-with-nested-objects.md go /usr/bin/git re GO111MODULE 64/bin/go git -C /tmp/gh-aw-test-runs/20260325-122213-65664/test-2526456105 rev-parse /usr/bin/git @{u} GO111MODULE 64/bin/go git(http block)/usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha --show-toplevel git /usr/bin/git --show-toplevel go /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel go /usr/bin/git git(http block)https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v4/usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq .object.sha 9104003/b435/sliceutil.test GO111MODULE 9104003/b435/importcfg.link GOINSECURE GOMOD GOMODCACHE 4vdN3eqAa1K0H/u1ogOOgsHoxcKHcseOEC/vKfaaJsUtRlxju1NbgiD/uvljh3C4vdN3eqAa1K0H -c ry=1 GOPROXY 0/x64/bin/node GOSUMDB GOWORK 64/bin/go bash(http block)/usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq .object.sha --show-toplevel git /usr/bin/git /tmp/gh-aw-test-git status /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git user.name Test User /usr/bin/git git(http block)https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.0.0/usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq .object.sha runs/20260325-122213-65664/test-566200507/.github/workflows GO111MODULE 9104003/b001/vet.cfg GOINSECURE GOMOD GOMODCACHE sh -c k/gh-aw/gh-aw/.github/workflows GOPROXY ache/go/1.25.0/x64/pkg/tool/linux_amd64/link GOSUMDB GOWORK 64/bin/go ache/go/1.25.0/x64/pkg/tool/linux_amd64/link(http block)/usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq .object.sha 999 git /usr/bin/git .github/workflowgit go /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel go /usr/bin/gh git(http block)https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.2.3/usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq .object.sha 999 GO111MODULE /home/REDACTED/.dotnet/tools/sh GOINSECURE GOMOD GOMODCACHE sh -c k/gh-aw/gh-aw/.github/workflows GOPROXY ache/go/1.25.0/x64/pkg/tool/linux_amd64/compile GOSUMDB GOWORK 64/bin/go ache/go/1.25.0/x64/pkg/tool/linux_amd64/compile(http block)/usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq .object.sha --show-toplevel git /usr/bin/git /tmp/gh-aw-test-git rev-parse /usr/bin/git git rev-�� --show-toplevel git /usr/bin/gh --git-dir go /opt/hostedtoolc--show-toplevel gh(http block)https://api.github.com/repos/github/gh-aw/actions/runs/1/artifacts/usr/bin/gh gh run download 1 --dir test-logs/run-1 GO111MODULE x_amd64/link GOINSECURE GOMOD GOMODCACHE x_amd64/link env -json GO111MODULE 0/x64/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin/sh GOINSECURE GOMOD GOMODCACHE ef/N6GE9dzJuLpfUe9tz4e_/ThKvzodBlPIPkS6j74YO(http block)https://api.github.com/repos/github/gh-aw/actions/runs/12345/artifacts/usr/bin/gh gh run download 12345 --dir test-logs/run-12345 GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/github/gh-aw/actions/runs/12346/artifacts/usr/bin/gh gh run download 12346 --dir test-logs/run-12346 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go estl�� -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/github/gh-aw/actions/runs/2/artifacts/usr/bin/gh gh run download 2 --dir test-logs/run-2 GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json GO111MODULE bin/sh GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/github/gh-aw/actions/runs/3/artifacts/usr/bin/gh gh run download 3 --dir test-logs/run-3 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile(http block)https://api.github.com/repos/github/gh-aw/actions/runs/4/artifacts/usr/bin/gh gh run download 4 --dir test-logs/run-4 GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/github/gh-aw/actions/runs/5/artifacts/usr/bin/gh gh run download 5 --dir test-logs/run-5 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE x_amd64/link GOINSECURE GOMOD GOMODCACHE x_amd64/link(http block)https://api.github.com/repos/github/gh-aw/actions/workflows/usr/bin/gh gh workflow list --json name,state,path --check **/*.cjs 64/bin/go **/*.json --ignore-path ../../../.pretti"prettier" --check '**/*.cjs' '**/*.ts' '**/*.json' --ignore-path ../../../.prettierignore go env -json GO111MODULE modules/@npmcli/run-script/lib/node-gyp-bin/node GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 100 GOMOD GOMODCACHE go env re GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 6 GOMOD GOMODCACHE go env -json GO111MODULE 0/x64/bin/sh GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.0.0/usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha -json GO111MODULE At,event,headBranch,headSha,displayTitle GOINSECURE GOMOD GOMODCACHE go env int:cjs GO111MODULE de_modules/.bin/sh GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha --show-toplevel go /usr/bin/git -json GO111MODULE /home/REDACTED/.lo--show-toplevel git rev-�� --show-toplevel sh /usr/bin/git tructions-test-3git GOPROXY /home/REDACTED/.do--show-toplevel git(http block)https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.2.3/usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.2.3 --jq .object.sha ath ../../../.pr**/*.json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go er -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/github/gh-aw/git/ref/tags/v2.0.0/usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq .object.sha ath ../../../.pr.prettierignore GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go er -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/github/gh-aw/git/ref/tags/v3.0.0/usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v3.0.0 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go er -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/nonexistent/action/git/ref/tags/v999.999.999/usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha -json GO111MODULE n-dir/node GOINSECURE GOMOD GOMODCACHE Ah/irCVNlwFVr1e4kQn-6MP/w6Oxv7UArev-parse 0/x6�� ithout_min-integrity1608438919/001 GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile(http block)/usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha --show-toplevel go /usr/bin/git -json GO111MODULE /opt/hostedtoolc--show-toplevel git rev-�� --show-toplevel sh /usr/bin/git ithub-script/gitgit GOPROXY /usr/local/bin/s--show-toplevel git(http block)https://api.github.com/repos/nonexistent/repo/actions/runs/12345/usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion GOINSECURE GOMOD GOMODCACHE go env 566200507/.github/workflows GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/owner/repo/actions/workflows/usr/bin/gh gh workflow list --json name,state,path --repo owner/repo 64/bin/go .prettierignore GOWORK 64/bin/go go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh workflow list --json name,state,path --repo owner/repo 64/bin/go --ignore-path .prettierignore 64/bin/go go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/owner/repo/contents/file.md/tmp/go-build2999104003/b402/cli.test /tmp/go-build2999104003/b402/cli.test -test.testlogfile=/tmp/go-build2999104003/b402/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true GOSUMDB GOWORK 64/bin/go bash --no�� --noprofile go 64/bin/go -json GO111MODULE 64/bin/go go(http block)https://api.github.com/repos/test-owner/test-repo/actions/secrets/usr/bin/gh gh api /repos/test-owner/test-repo/actions/secrets --jq .secrets[].name --check **/*.cjs 64/bin/go **/*.json --ignore-path ../../../.prettiprettier go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)If you need me to access, download, or install something from one of these locations, you can either:
💡 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.