Skip to content

Migrate GitHub App token input to client-id, add schema-level compatibility, and provide codemod migration#26551

Merged
pelikhan merged 4 commits intomainfrom
copilot/migrate-app-id-to-client-id
Apr 16, 2026
Merged

Migrate GitHub App token input to client-id, add schema-level compatibility, and provide codemod migration#26551
pelikhan merged 4 commits intomainfrom
copilot/migrate-app-id-to-client-id

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 16, 2026

Workflows using github-app checkout emitted upstream deprecation warnings because compiled jobs passed app-id to actions/create-github-app-token, while frontmatter rejected client-id. This change updates generation to use client-id and allows workflow authors to provide either field during migration.

  • Token minting output migration (app-idclient-id)

    • Updated all GitHub App token minting step generators to emit:
      • with.client-id
      • with.private-key
    • This removes the recurring deprecation warning from generated workflows.
  • Backward-compatible frontmatter/import parsing

    • github-app parsing now accepts both:
      • client-id (preferred)
      • app-id (legacy)
    • If both are present, client-id is preferred.
    • Import validation for merged github-app JSON now treats (client-id OR app-id) + private-key as valid.
  • Schema updates for author-facing compatibility

    • Updated github_app schema to support either required pair:
      • client-id + private-key, or
      • app-id + private-key
    • Kept app-id as a deprecated alias in schema/docs/examples where relevant to preserve compatibility while enabling migration.
  • Codemod support for automatic migration

    • Added a new gh aw fix codemod to migrate:
      • github-app.app-idgithub-app.client-id
    • Registered the codemod in the global codemod registry so existing workflows can be updated automatically.
    • Added focused tests to verify:
      • migration inside github-app blocks
      • no-op behavior when already migrated
      • no unintended rewrites for non-github-app app-id keys.
  • Error/help text and expectation updates

    • Updated validation/error copy to reflect client-id (or app-id) semantics.
    • Updated affected tests to assert client-id in compiled output and added coverage for parsing client-id in github-app.
checkout:
  - repository: my-org/my-repo
    github-app:
      client-id: ${{ vars.MY_APP_ID }}   # preferred
      private-key: ${{ secrets.MY_APP_KEY }}

[!WARNING]

Copilot AI changed the title [WIP] Migrate from app-id to client-id in GitHub App token generation Migrate GitHub App token input to client-id and add schema-level compatibility Apr 16, 2026
Copilot AI requested a review from pelikhan April 16, 2026 04:18
@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot add codemod to migrate

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 16, 2026

@copilot add codemod to migrate

Implemented in commit 2a4a427.

Added a new codemod that migrates github-app.app-id to github-app.client-id, registered it in the codemod registry, and added focused tests for migration + non-target safety behavior.

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 1295098/b224/vetrev-parse ache/go/1.25.8/x--show-toplevel git rev-�� --show-toplevel ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet /usr/bin/git -json GO111MODULE e/git git (http block)
    • 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 om/goccy/go-yamlrev-parse ache/go/1.25.8/x--show-toplevel git rev-�� --show-toplevel ache/go/1.25.8/x64/pkg/tool/linux_amd64/compile /usr/bin/git ApprovalLabelsCogit 3oGe/PFmiX04DWzKrev-parse ache/go/1.25.8/x--show-toplevel git (http block)
  • https://api.github.com/orgs/test-owner/actions/secrets
    • Triggering command: /usr/bin/gh gh api /orgs/test-owner/actions/secrets --jq .secrets[].name -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE 6AWy9kr/rVG28oB_-buildtags env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /orgs/test-owner/actions/secrets --jq .secrets[].name -json GO111MODULE ache/go/1.25.8/x-lang=go1.25 GOINSECURE GOMOD GOMODCACHE go env */*.ts' '**/*.js-p GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /orgs/test-owner/actions/secrets --jq .secrets[].name --show-toplevel git /usr/bin/git --get remote.origin.ur/home/REDACTED/.npm/_npx/b388654678d519d9/node_modules/.bin/prettier /usr/bin/git git rev-�� h ../../../.pret.prettierignore git /node GOMODCACHE x_amd64/asm /usr/bin/git git (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, .object.type] | @tsv --show-toplevel 64/pkg/tool/linux_amd64/vet /usr/bin/infocmp -json GO111MODULE 64/pkg/tool/linu--show-toplevel infocmp -1 xterm-color 64/pkg/tool/linux_amd64/vet /usr/bin/git -json GO111MODULE 64/pkg/tool/linu--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq [.object.sha, .object.type] | @tsv --show-toplevel runtime/atomic/atomic_wasm.s /usr/bin/git -json GO111MODULE 64/pkg/tool/linu--show-toplevel git rev-�� --show-toplevel 64/pkg/tool/linux_amd64/asm e/git-remote-https lint:cjs @v1.1.3/base64/brev-parse 64/pkg/tool/linu--show-toplevel e/git-remote-https (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, .object.type] | @tsv e: ${{ secrets.TOKEN }} rev-parse /usr/bin/git -json GO111MODULE 64/bin/go git rev-�� --show-toplevel go /usr/bin/git -json GO111MODULE x_amd64/vet git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq [.object.sha, .object.type] | @tsv /tmp/TestHashConsistency_GoAndJavaScript4038023613/001/test-simple-frontmatter.md -pack /usr/bin/git 43884501/001' 43884501/001' ode git -C /tmp/TestGuardPolicyTrustedUsersRequiresMinIntegrity772017858/001 l /usr/bin/git remote.origin.urgit GO111MODULE 64/bin/go git (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, .object.type] | @tsv ger.test 1295098/b260/vet.cfg ortcfg.link GOINSECURE GOMOD GOMODCACHE PfVSWh7piXGOU8tx^remote\..*\.gh-resolved$ env 2608-30263/test-3918340885/.github/workflows GO111MODULE g_.a GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq [.object.sha, .object.type] | @tsv --show-toplevel 64/pkg/tool/linutest@example.com /usr/bin/git til.go o 64/pkg/tool/linu--show-toplevel git rev-�� it/ref/tags/v4 64/pkg/tool/linux_amd64/compile sv g_.a 1295098/b044/vetrev-parse .cfg git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq [.object.sha, .object.type] | @tsv --show-toplevel /opt/hostedtoolcache/go/1.25.8/x-importcfg /usr/bin/git licyTrustedUsersgit /tmp/go-build318rev-parse .cfg git rev-�� --show-toplevel /opt/hostedtoolcache/go/1.25.8/x-extld=gcc /usr/bin/git -bool -buildtags /usr/lib/git-cor--show-toplevel git (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, .object.type] | @tsv --show-toplevel ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet /usr/bin/git se 1295098/b055/vetcommit .cfg git rev-�� --show-toplevel ache/go/1.25.8/x2 /usr/bin/git Onlymin-integritgit 1295098/b232/vetrev-parse ache/go/1.25.8/x--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq [.object.sha, .object.type] | @tsv --show-toplevel 64/pkg/tool/linux_amd64/vet /usr/bin/git Elygkb-do GO111MODULE x_amd64/vet git rev-�� --show-toplevel x_amd64/vet /usr/bin/git 5358846/b096/_pkgit om/google/jsonscrev-parse .cfg git (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v9
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv /tmp/go-build351-errorsas -trimpath 64/bin/go -p github.com/githu-unsafeptr=false -lang=go1.25 go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet (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, .object.type] | @tsv = get && echo "******"; }; f get = get && echo "******"; }; f get /usr/bin/git 55711/001 GO111MODULE x_amd64/vet git init�� GOMODCACHE x_amd64/vet /usr/bin/git -json GO111MODULE 64/pkg/tool/linu--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv /tmp/gh-aw-test-runs/20260416-044021-62156/test-3208797231 status /usr/bin/git .github/workflowgit GO111MODULE x_amd64/compile git rev-�� --show-toplevel x_amd64/compile /usr/bin/git 711306/b365/_pkggit GO111MODULE 64/bin/go git (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, .object.type] | @tsv om/owner/repo.git om/owner/repo.git /usr/bin/git -json GO111MODULE x_amd64/vet git rev-�� --show-toplevel x_amd64/vet /usr/bin/git -json GO111MODULE 64/pkg/tool/linu--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv --git-dir x_amd64/compile /usr/bin/git tmatter-with-nesgit GO111MODULE x_amd64/compile git rev-�� --show-toplevel x_amd64/compile /usr/bin/git -json GO111MODULE x_amd64/vet git (http block)
  • https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv /tmp/go-build3181295098/b417/_pkg_.a -trimpath /usr/bin/infocmp -p github.com/githurev-parse -lang=go1.25 infocmp -1 xterm-color -goversion /usr/bin/git -c=4 -nolocalimports -importcfg git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv runs/20260416-044021-62156/test-520983282 -trimpath /usr/lib/git-core/git -p net/http/internarev-parse -lang=go1.25 /usr/lib/git-core/git rev-�� --objects l e/git --exclude-hiddengit --all --quiet e/git (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v0.1.2
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v0.1.2 --jq [.object.sha, .object.type] | @tsv /home/REDACTED/work/gh-aw/gh-aw/.github/workflows/agent-performance-analyzer.md x_amd64/vet /usr/bin/git -json GO111MODULE x_amd64/vet git rev-�� --show-toplevel x_amd64/vet /usr/bin/git -json GO111MODULE 64/pkg/tool/linu--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v0.1.2 --jq [.object.sha, .object.type] | @tsv /tmp/gh-aw-test-runs/20260416-044021-62156/test-3208797231 status /usr/bin/git .github/workflowgit GO111MODULE x_amd64/compile git rev-�� --show-toplevel x_amd64/compile (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq [.object.sha, .object.type] | @tsv sistency_GoAndJavaScript1441108425/001/test-frontmatter-with-arr-test.timeout=10m0s -trimpath /usr/bin/git -p github.com/githurev-parse -lang=go1.25 git -C ithub-script/git/ref/tags/v9 config bject.type] | @tsv remote.origin.urgit -nolocalimports -importcfg git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq [.object.sha, .object.type] | @tsv /tmp/go-build3345358846/b240/_pkg_.a -trimpath /usr/lib/git-core/git -p golang.org/x/texrev-parse -lang=go1.25 /usr/lib/git-core/git unpa�� --pack_header=2,3 l e/git go1.25.8 -c=4 nch,headSha,disp--show-toplevel e/git (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.2.3
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq [.object.sha, .object.type] | @tsv /tmp/go-build3181295098/b415/fileutil.test -importcfg /usr/bin/git -s -w -buildmode=exe git rev-�� ons-test3138065628 -extld=gcc /usr/bin/git -json GO111MODULE 64/bin/go git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq [.object.sha, .object.type] | @tsv ithub-script/git/ref/tags/v9 -trimpath bject.type] | @tsv -p golang.org/x/texrev-parse -lang=go1.25 git-receive-pack /tmp�� hp-KJ12h06fdYFiwu7NJ/hp-KJ12h06fdYFiwu7NJ -dwarf=false /usr/bin/git go1.25.8 -c=4 -nolocalimports git (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/1/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/1/artifacts --jq .artifacts[].name GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet ortc�� -json stmain.go x_amd64/link GOINSECURE GOMOD GOMODCACHE x_amd64/link (http block)
    • Triggering command: /usr/bin/gh gh run download 1 --dir test-logs/run-1 .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env 1037547477/custom/workflows verutil_test.go ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu--jq (http block)
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/1/artifacts --jq .artifacts[].name GO111MODULE At,event,headBranch,headSha,displayTitle GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet ortc�� 5358846/b209/_pkg_.a om/goccy/go-yaml@v1.19.2/context.go .cfg GOINSECURE g/x/crypto/interrev-parse GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linux_amd64/compile (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12345/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/12345/artifacts --jq .artifacts[].name GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linutest@example.com env 1830694501 GO111MODULE .cfg GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu-trimpath (http block)
    • Triggering command: /usr/bin/gh gh run download 12345 --dir test-logs/run-12345 GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linuTest User env -json GO111MODULE .cfg GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu-test.v=true (http block)
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/12345/artifacts --jq .artifacts[].name QuPWq4ACQ ache/go/1.25.8/x64/pkg/tool/linux_amd64/asm GOINSECURE chema/v6/kind GOMODCACHE ache/go/1.25.8/x--jq env -RlDlG6ki GO111MODULE ache/go/1.25.8/x64/pkg/tool/linux_amd64/compile GOINSECURE 5358846/b029/ GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linuremote2 (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12346/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/12346/artifacts --jq .artifacts[].name GO111MODULE 64/pkg/tool/linu-importcfg GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linu/home/REDACTED/work/gh-aw/gh-aw/pkg/timeutil/format_test.go env 1830694501 GO111MODULE .cfg GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu-importcfg (http block)
    • Triggering command: /usr/bin/gh gh run download 12346 --dir test-logs/run-12346 GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env -json GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/12346/artifacts --jq .artifacts[].name deRMpwyMD ck GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linux_amd64/compile sRem�� ITIJ8Hyq- GO111MODULE ache/go/1.25.8/x64/pkg/tool/linux_amd64/compile GOINSECURE /math GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linuremote1 (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/2/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/2/artifacts --jq .artifacts[].name GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env -json GO111MODULE .cfg GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linurev-parse (http block)
    • Triggering command: /usr/bin/gh gh run download 2 --dir test-logs/run-2 .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env plorer.md GO111MODULE ache/go/1.25.8/x64/pkg/tool/linu-buildmode=exe GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu-test.v=true (http block)
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/2/artifacts --jq .artifacts[].name BytXhgNOP 1/x64/bin/node GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linux_amd64/asm -has�� vaScript4038023613/001/test-simple-frontmatter.md GO111MODULE ache/go/1.25.8/x64/pkg/tool/linux_amd64/compile GOINSECURE 5358846/b011/ GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linutest@example.com (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/3/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/3/artifacts --jq .artifacts[].name .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env -json GO111MODULE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linuconfig (http block)
    • Triggering command: /usr/bin/gh gh run download 3 --dir test-logs/run-3 .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env -json GO111MODULE 64/pkg/tool/linux_amd64/compile GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/compile (http block)
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/3/artifacts --jq .artifacts[].name GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet ortc�� GCB45Yj4t om/segmentio/encoding@v0.5.4/json/codec.go ache/go/1.25.8/x64/pkg/tool/linux_amd64/compile GOINSECURE g/x/crypto/cryptrev-parse GOMODCACHE ortcfg (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/4/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/4/artifacts --jq .artifacts[].name GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linuTest User env -json GO111MODULE .cfg GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh run download 4 --dir test-logs/run-4 .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env 1037547477 GO111MODULE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/4/artifacts --jq .artifacts[].name GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet ortc�� 5358846/b198/_pkg_.a om/modelcontextprotocol/go-sdk@v1.5.0/internal/util/net.go .cfg GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linuTest User (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/5/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/5/artifacts --jq .artifacts[].name GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env -json GO111MODULE k GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linuremote (http block)
    • Triggering command: /usr/bin/gh gh run download 5 --dir test-logs/run-5 .cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env 1037547477/custom/workflows GO111MODULE 64/pkg/tool/linux_amd64/compile GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/compile (http block)
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/5/artifacts --jq .artifacts[].name diXaaNED5 ache/go/1.25.8/x64/pkg/tool/linux_amd64/compile GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linuTest User env ortcfg GO111MODULE .cfg GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linux_amd64/compile (http block)
  • https://api.github.com/repos/github/gh-aw/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path -c=4 -nolocalimports -importcfg /tmp/go-build3181295098/b414/importcfg -pack /home/REDACTED/work/gh-aw/gh-aw/pkg/fileutil/fileutil.go /home/REDACTED/work/gh-aw/gh-aw/pkg/fileutil/tar.go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /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 x_amd64/vet env -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet (http block)
    • Triggering command: /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 64/pkg/tool/linux_amd64/vet env -json GO111MODULE .cfg GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/xorigin (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v0.47.4
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v0.47.4 --jq [.object.sha, .object.type] | @tsv --show-toplevel 64/pkg/tool/linux_amd64/vet /usr/bin/git 1295098/b464/_pkgit .cfg ache/go/1.25.8/x--show-toplevel git rev-�� --show-toplevel ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet /usr/bin/git se 1295098/b144/vet-lh ache/go/1.25.8/x/tmp/gh-aw/aw-feature-branch.patch git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v0.47.4 --jq [.object.sha, .object.type] | @tsv --show-toplevel gh-aw.opt.wasm gh-aw.wasm; \ AFrev-parse /usr/bin/git 01/main.md 1y3cTijPK 64/pkg/tool/linu--show-toplevel /usr/bin/git conf�� --get-regexp ^remote\..*\.gh-resolved$ /usr/bin/git agent-persona-exls 1T9iaPhBz 1/x64/bin/node git (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, .object.type] | @tsv -json GO111MODULE sole.test GOINSECURE GOMOD GOMODCACHE sole.test 1812�� 25/001/test-complex-frontmatter-with-tools.md 1295098/b041/vet.cfg .cfg GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linu--auto (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq [.object.sha, .object.type] | @tsv run lint:cjs 64/pkg/tool/linux_amd64/compile GOSUMDB GOWORK 64/bin/go 64/pkg/tool/linuupstream /opt�� g_.a --check 64/pkg/tool/linux_amd64/compile --ignore-path o8601 64/src/internal/--git-dir 64/pkg/tool/linux_amd64/compile (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.2.3
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.2.3 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.2.3 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json f x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.2.3 --jq [.object.sha, .object.type] | @tsv js/**/*.json' ---errorsas git /usr/bin/git --show-toplevel x_amd64/compile /usr/bin/git git rev-�� 1 1 git /usr/bin/git --show-toplevel go /usr/bin/git git (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v2.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet 1988�� -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile 3884�� -json GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v3.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v3.0.0 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env 1988338/001 1988338/002/work x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v3.0.0 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile 3295�� -json GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v3.0.0 --jq [.object.sha, .object.type] | @tsv js/**/*.json' ---s git /usr/bin/git --git-dir x_amd64/compile /usr/bin/git git rev-�� --show-toplevel git node --show-toplevel x_amd64/vet /usr/bin/git git (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, .object.type] | @tsv -json .cfg util.test GOINSECURE GOMOD GOMODCACHE util.test 1812�� 25/001/test-complex-frontmatter-with-tools.md 1295098/b042/vet.cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq [.object.sha, .object.type] | @tsv npx prettier --check '**/*.cjs' remote.origin.url GOPROXY 64/pkg/tool/linux_amd64/compile GOSUMDB GOWORK 64/bin/go 64/pkg/tool/linuremote2 -c y_with_repos=public_390163265/001 ri/jsonschema/v6@v6.0.2/kind/kind.go 64/pkg/tool/linux_amd64/compile tierignore scripts/**/*.js abis 64/pkg/tool/linux_amd64/compile (http block)
  • https://api.github.com/repos/nonexistent/repo/actions/runs/12345
    • Triggering command: /usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env -json .cfg 64/pkg/tool/linux_amd64/compile GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/compile (http block)
    • Triggering command: /usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion GOINSECURE 5358846/b011/ GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linux_amd64/compile env 5358846/b172/_pkg_.a GO111MODULE ache/go/1.25.8/x64/pkg/tool/linux_amd64/compile GOINSECURE 5358846/b011/int-1 ache/go/1.25.8/xxterm-color ache/go/1.25.8/x64/pkg/tool/linux_amd64/compile (http block)
    • Triggering command: /usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion --show-toplevel ache/go/1.25.8/xconfig /usr/bin/git git rev-�� */*.json' '!../../../pkg/workflow/js/**/*.json' --ignore-path git 64/pkg/tool/linux_amd64/vet --show-toplevel ache/go/1.25.8/xrev-parse /usr/bin/git 64/pkg/tool/linux_amd64/vet (http block)
  • https://api.github.com/repos/owner/repo/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo -nolocalimports -importcfg /tmp/go-build3181295098/b418/importcfg -pack /tmp/go-build3181295098/b418/_testmain.go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo ules/.bin/node GOINSECURE GOMOD GOMODCACHE go tion�� -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/owner/repo/contents/file.md
    • Triggering command: /tmp/go-build3181295098/b400/cli.test /tmp/go-build3181295098/b400/cli.test -test.testlogfile=/tmp/go-build3181295098/b400/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true -d unsafe 64/bin/go go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /tmp/go-build2522887495/b400/cli.test /tmp/go-build2522887495/b400/cli.test -test.testlogfile=/tmp/go-build2522887495/b400/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true -nolocalimports -importcfg /tmp/go-build3345358846/b177/importcfg -pack env -json GO111MODULE ules/.bin/node GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /tmp/go-build2200792584/b400/cli.test /tmp/go-build2200792584/b400/cli.test -test.testlogfile=/tmp/go-build2200792584/b400/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true xterm-color go /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --get remote.origin.ur-c /usr/lib/git-cornpx prettier --write '../../../**/*.json' '!../../../pkg/workflow/js/**/*.json' --ignore-path git (http block)
  • https://api.github.com/repos/test-owner/test-repo/actions/secrets
    • Triggering command: /usr/bin/gh gh api /repos/test-owner/test-repo/actions/secrets --jq .secrets[].name -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/test-owner/test-repo/actions/secrets --jq .secrets[].name -json GO111MODULE ndor/bin/sh GOINSECURE GOMOD GOMODCACHE go env */*.ts' '**/*.js-p GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/test-owner/test-repo/actions/secrets --jq .secrets[].name --show-toplevel git /usr/bin/git GOMODCACHE go /usr/bin/git git rev-�� h ../../../.pret.prettierignore git /opt/hostedtoolcache/node/24.14.1/x64/bin/node /home/REDACTED/wormake config /usr/bin/git node (http block)

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

Copilot AI changed the title Migrate GitHub App token input to client-id and add schema-level compatibility Migrate GitHub App token input to client-id, add schema-level compatibility, and provide codemod migration Apr 16, 2026
@pelikhan pelikhan marked this pull request as ready for review April 16, 2026 05:05
Copilot AI review requested due to automatic review settings April 16, 2026 05:05
Copy link
Copy Markdown
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

This PR migrates GitHub App token minting from app-id to client-id to eliminate upstream deprecation warnings, while keeping backward compatibility via parsing/schema support and providing an automatic codemod.

Changes:

  • Updated workflow generation to emit with.client-id (instead of with.app-id) for actions/create-github-app-token.
  • Added backward-compatible parsing/validation so configs can use client-id (preferred) or legacy app-id.
  • Updated JSON schema and added a new gh aw fix codemod to migrate github-app.app-idgithub-app.client-id, with tests.
Show a summary per file
File Description
pkg/workflow/workflow_github_app.go Emits client-id when injecting top-level github-app fallback into tools map.
pkg/workflow/top_level_github_app_integration_test.go Updates integration assertions to expect client-id in compiled output.
pkg/workflow/skip_if_no_match_test.go Updates minted-step assertions to expect client-id.
pkg/workflow/skip_if_match_test.go Updates minted-step assertions to expect client-id.
pkg/workflow/safe_outputs_validation.go Updates user-facing guidance text to show client-id.
pkg/workflow/safe_outputs_app_config.go Accepts client-id or legacy app-id on input; emits client-id in generated steps.
pkg/workflow/github_mcp_app_token_test.go Updates GitHub MCP token minting assertions to expect client-id.
pkg/workflow/github_app_permissions_validation.go Updates error/help text examples to use client-id.
pkg/workflow/frontmatter_extraction_yaml.go Recognizes client-id: as a nested github-app field in YAML scanning logic.
pkg/workflow/compiler_pre_activation_job.go Emits client-id in pre-activation token minting step.
pkg/workflow/compiler_github_mcp_steps.go Updates logging text to reference client-id.
pkg/workflow/checkout_manager_test.go Adds parsing coverage for client-id and updates error-message expectations.
pkg/workflow/checkout_config_parser.go Updates validation error message to mention client-id (or app-id).
pkg/workflow/activation_github_token_test.go Updates activation token minting assertions to expect client-id.
pkg/parser/schemas/main_workflow_schema.json Adds client-id, keeps app-id as legacy, and makes required-ness anyOf for compatibility.
pkg/parser/schema_test.go Adds schema validation test coverage for github-app.client-id.
pkg/parser/import_field_extractor.go Treats (client-id OR app-id) + private-key as valid for imported github-app JSON detection.
pkg/cli/fix_codemods_test.go Updates codemod registry tests for the newly added codemod.
pkg/cli/fix_codemods.go Registers the new github-app app-id→client-id codemod.
pkg/cli/codemod_github_app_client_id_test.go Adds focused tests for the new migration codemod behavior.
pkg/cli/codemod_github_app_client_id.go Implements the codemod that renames app-id: to client-id: within github-app blocks.

Copilot's findings

Tip

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

Comments suppressed due to low confidence (2)

pkg/workflow/safe_outputs_app_config.go:45

  • parseAppConfig prefers client-id when present, but if client-id exists with a non-string (or empty) value and a valid legacy app-id is also provided, the current if/else prevents falling back to app-id, leaving AppID empty and causing validation to fail. Consider only preferring client-id when it parses to a non-empty string; otherwise, fall back to app-id (and optionally log/return an error for invalid types).
	// Parse client-id/app-id (required)
	// Prefer client-id when both are provided; app-id is accepted for backward compatibility.
	if clientID, exists := appMap["client-id"]; exists {
		if clientIDStr, ok := clientID.(string); ok {
			appConfig.AppID = clientIDStr
		}
	} else if appID, exists := appMap["app-id"]; exists {
		if appIDStr, ok := appID.(string); ok {
			appConfig.AppID = appIDStr
		}
	}

pkg/parser/import_field_extractor.go:531

  • validateGitHubAppJSON only checks for the presence of client-id/app-id and private-key keys, not that they are non-empty strings. Because import extraction is first-wins, an imported workflow with client-id: null (or numeric) can be treated as “valid” here, block later valid configs, and then fail parsing in resolveTopLevelGitHubApp. Tighten validation to require a non-empty string for whichever ID field is present (prefer client-id if both) and for private-key.
// validateGitHubAppJSON validates that a JSON-encoded GitHub App configuration has the required
// fields ((client-id or app-id) and private-key). Returns the input JSON if valid, or "" otherwise.
func validateGitHubAppJSON(appJSON string) string {
	if appJSON == "" || appJSON == "null" {
		return ""
	}
	var appMap map[string]any
	if err := json.Unmarshal([]byte(appJSON), &appMap); err != nil {
		return ""
	}
	_, hasClientID := appMap["client-id"]
	_, hasAppID := appMap["app-id"]
	if !hasClientID && !hasAppID {
		return ""
	}
	if _, hasKey := appMap["private-key"]; !hasKey {
		return ""
	}
	return appJSON
  • Files reviewed: 21/21 changed files
  • Comments generated: 1

"app-id": {
"type": "string",
"description": "GitHub App ID (e.g., '${{ vars.APP_ID }}'). Required to mint a GitHub App token.",
"description": "Deprecated alias for client-id. GitHub App ID/client ID (e.g., '${{ vars.APP_ID }}').",
@github-actions
Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 72/100

⚠️ Acceptable — test quality is good with one minor note

Metric Value
New/modified tests analyzed 16
✅ Design tests (behavioral contracts) 14 (87%)
⚠️ Implementation tests (low value) 2 (13%)
Tests with error/edge cases 9 (56%)
Duplicate test clusters 0
Test inflation detected Yes (1 file)
🚨 Coding-guideline violations 0

Test Classification Details

View All Test Classifications (16 tests)
Test File Classification Notes
TestGitHubAppClientIDCodemod / "renames app-id under github-app blocks" pkg/cli/codemod_github_app_client_id_test.go:14 ✅ Design Verifies migration across top-level, on, checkout contexts
TestGitHubAppClientIDCodemod / "does not modify content without github-app.app-id" pkg/cli/codemod_github_app_client_id_test.go:64 ✅ Design Edge case: idempotency
TestGitHubAppClientIDCodemod / "does not rename app-id outside github-app blocks" pkg/cli/codemod_github_app_client_id_test.go:83 ✅ Design Edge case: scoped rename guard
TestValidateMainWorkflowFrontmatterWithSchemaAndLocation_GitHubAppClientID pkg/parser/schema_test.go:499 ✅ Design Verifies schema accepts client-id
TestParseCheckoutConfigs / "github-app config accepts client-id" pkg/workflow/checkout_manager_test.go:301 ✅ Design Behavioral: new field parsed into AppID
TestParseCheckoutConfigs / missing app-id error message pkg/workflow/checkout_manager_test.go:337 ✅ Design Error path: updated message assertion
TestParseCheckoutConfigs / missing private-key error message pkg/workflow/checkout_manager_test.go:347 ✅ Design Error path: updated message assertion
TestActivationGitHubApp (2 assertions) pkg/workflow/activation_github_token_test.go:117,349 ✅ Design Behavioral: compiled output field updated
TestGitHubMCPAppToken (2 assertions) pkg/workflow/github_mcp_app_token_test.go:100,259 ✅ Design Behavioral: compiled YAML field updated
TestSkipIfMatchWorkflow pkg/workflow/skip_if_match_test.go:427 ✅ Design Behavioral: token mint step field updated
TestSkipIfNoMatchWorkflow pkg/workflow/skip_if_no_match_test.go:486 ✅ Design Behavioral: token mint step field updated
TestTopLevelGitHubApp* (5 sub-tests + file tests) pkg/workflow/top_level_github_app_integration_test.go ✅ Design Behavioral: compiled YAML field updated
TestGetAllCodemods_ReturnsAllCodemods (count) pkg/cli/fix_codemods_test.go:46 ⚠️ Implementation Count-only assertion; brittle to ordering
TestGetAllCodemods_InExpectedOrder (order) pkg/cli/fix_codemods_test.go:130 ⚠️ Implementation Verifies codemod list order; fragile

Flagged Tests — Requires Review

⚠️ TestGetAllCodemods_ReturnsAllCodemods / TestGetAllCodemods_InExpectedOrder (pkg/cli/fix_codemods_test.go)

Classification: Implementation tests
Issue: Both tests assert on internal list structure (exact count: 30, and a hardcoded ordered slice of codemod names). They verify how codemods are registered, not what they do.
What design invariant does this test enforce? That a specific count and order of codemods exists — an internal registration detail.
What would break if deleted? Only if a developer adds/reorders codemods without updating the list. A behavioral regression (codemod producing wrong output) would not be caught.
Suggested improvement: These registry tests provide useful guard-rails against accidental deletion of a codemod. They are acceptable as-is; the low-value classification is purely technical. If the ordered-list test becomes a maintenance burden, consider replacing the order assertion with a "codemod is present" check plus a separate integration test that verifies each codemod applies correctly end-to-end.


Inflation Note

pkg/workflow/checkout_manager_test.go added 17 lines vs 1 line in checkout_config_parser.go (17:1 ratio, exceeds 2:1 threshold).

This is contextually justified: the single production-line change (field name in parser) required adding a new acceptance test for client-id and updating two error-message assertions. The tests themselves are high quality. The inflation flag is a mechanical artifact of the ratio calculation, not a genuine quality concern here.


Language Support

Tests analyzed:

  • 🐹 Go (*_test.go): 16 test cases — unit (//go:build !integration) and integration (//go:build integration)
  • 🟨 JavaScript (*.test.cjs, *.test.js): 0 tests changed

Build Tag Check ✅

New file pkg/cli/codemod_github_app_client_id_test.go correctly starts with //go:build !integration on line 1. No violations.


Verdict

Check passed. 13% of new tests are implementation tests (threshold: 30%). No coding-guideline violations detected. The bulk of changes are high-value behavioral assertions updated to reflect the app-idclient-id field rename, plus a well-structured new codemod test with idempotency and scope-guard edge cases.


📖 Understanding Test Classifications

Design Tests (High Value) verify what the system does:

  • Assert on observable outputs, return values, or state changes
  • Cover error paths and boundary conditions
  • Would catch a behavioral regression if deleted
  • Remain valid even after internal refactoring

Implementation Tests (Low Value) verify how the system does it:

  • Assert on internal function calls or data structure counts
  • Break during legitimate refactoring even when behavior is correct
  • Give false assurance: they pass even when the system is wrong

Goal: Shift toward tests that describe the system's behavioral contract — the promises it makes to its users and collaborators.

References: §24493163527

🧪 Test quality analysis by Test Quality Sentinel · ● 527.4K ·

Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

✅ Test Quality Sentinel: 72/100. Test quality is acceptable — 13% of new tests are implementation tests (threshold: 30%). No coding-guideline violations detected. The new codemod test covers idempotency and scope-guard edge cases well.

Generated by the Design Decision Gate workflow to document the
architectural decision to migrate `app-id` → `client-id` in GitHub App
token configuration, with backward-compatible parsing and codemod support.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

Commit pushed: 0f00e0f

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions
Copy link
Copy Markdown
Contributor

🏗️ Design Decision Gate — ADR Required

This PR makes significant changes to core business logic in pkg/ (316 new lines) but does not have a linked Architecture Decision Record (ADR).

AI has analyzed the PR diff and generated a draft ADR to help you get started:

📄 Draft ADR: docs/adr/26551-migrate-github-app-token-input-to-client-id.md

What the draft covers

The generated ADR documents the three interrelated design decisions in this PR:

  1. Compiled output migration — generated actions/create-github-app-token steps now always emit client-id, eliminating upstream deprecation warnings.
  2. Backward-compatible parsing — frontmatter parser accepts both client-id (preferred) and app-id (legacy alias), using client-id when both are present.
  3. Codemod-based migration path — a new github-app-app-id-to-client-id codemod allows authors to migrate existing workflows automatically via gh aw fix.

What to do next

  1. Review the draft ADR committed to your branch — it was generated from the PR diff
  2. Complete any missing sections — add context the AI couldn't infer (e.g., the specific upstream action version that introduced the deprecation, any timeline for removing app-id support, stakeholder decisions about the migration window)
  3. Reference the ADR in this PR body by adding a line such as:

    ADR: ADR-26551: Migrate GitHub App Token Input from app-id to client-id

Once an ADR is linked in the PR body, this gate will re-run and verify the implementation matches the decision.

Why ADRs Matter

"AI made me procrastinate on key design decisions. Because refactoring was cheap, I could always say 'I'll deal with this later.' Deferring decisions corroded my ability to think clearly."

ADRs create a searchable, permanent record of why the codebase looks the way it does. Future contributors (and your future self) will thank you.


📋 Michael Nygard ADR Format Reference

An ADR must contain these four sections to be considered complete:

  • Context — What is the problem? What forces are at play?
  • Decision — What did you decide? Why?
  • Alternatives Considered — What else could have been done?
  • Consequences — What are the trade-offs (positive and negative)?

All ADRs are stored in docs/adr/ as Markdown files numbered by PR number (e.g., 26551-migrate-github-app-token-input-to-client-id.md for PR #26551).

🔒 This PR cannot merge until an ADR is linked in the PR body.

References: §24493163553

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · ● 145.2K ·

@pelikhan pelikhan merged commit ce15603 into main Apr 16, 2026
@pelikhan pelikhan deleted the copilot/migrate-app-id-to-client-id branch April 16, 2026 05:18
This was referenced Apr 16, 2026
github-actions bot added a commit that referenced this pull request Apr 16, 2026
…ment object form

- Add byok-copilot feature flag subsection to frontmatter.md
  (from #26544: bundles cli-proxy, COPILOT_API_KEY injection, and
   latest Copilot CLI install behind a single flag)
- Update all github-app examples to use client-id (preferred) instead
  of app-id (deprecated alias) across auth.mdx, checkout.md, faq.md,
  imports.md, safe-outputs.md, safe-outputs-pull-requests.md, tokens.md,
  triggers.md, and glossary.md (from #26551: run gh aw fix to auto-migrate)
- Add object-form documentation for status-comment in triggers.md, with
  issues/pull-requests/discussions toggle fields (from #26535)
- Update status-comment description in frontmatter.md to mention object form

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

app-id deprecation warning — migrate to client-id in GitHub App token generation

3 participants