Skip to content

perf: eliminate repeated O(n) action pin scans and redundant permissions parsing in MCP workflow compilation#24256

Draft
Copilot wants to merge 2 commits intomainfrom
copilot/fix-compile-mcp-workflow-performance
Draft

perf: eliminate repeated O(n) action pin scans and redundant permissions parsing in MCP workflow compilation#24256
Copilot wants to merge 2 commits intomainfrom
copilot/fix-compile-mcp-workflow-performance

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 3, 2026

BenchmarkCompileMCPWorkflow was reported ~20% slower than baseline. Profiling identified two allocation hotspots unrelated to runner variance.

Changes

O(1) per-repo action pin index (action_pins.go)

Every call to GetActionPin / GetActionPinWithData / GetActionPinByRepo invoked sliceutil.Filter to scan all 38 pins and allocate a fresh result slice. A typical MCP workflow references ~23 actions, so each compilation did 23+ linear scans.

A map[string][]ActionPin index is now built once in the sync.Once initializer alongside cachedActionPins. Each repo's slice is pre-sorted by semantic version descending, so the per-call sortPinsByVersion copy+sort pass is also eliminated. The three public functions now delegate to getActionPinsByRepo(repo) — an O(1) map read with no allocation.

Result: ~290 fewer allocations/op, ~55 KB less heap/op (1,550,985 → 1,495,886 B/op).

// before — called on every GetActionPin* invocation
matchingPins := sliceutil.Filter(actionPins, func(pin ActionPin) bool {
    return pin.Repo == actionRepo
})
matchingPins = sortPinsByVersion(matchingPins)

// after — zero allocation, already sorted
matchingPins := getActionPinsByRepo(actionRepo) // O(1) map lookup

Single permissions parse per validation pass (compiler.go)

NewPermissionsParser(workflowData.Permissions).ToPermissions() (which runs a YAML parser) was called three times with the same string inside validateWorkflowData. The result is now parsed once into cachedPermissions and shared across the GitHub MCP toolset check, the id-token:write warning, and the agentic-workflows actions:read check.

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)
    • 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 /opt/hostedtoolcrev-parse /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel /opt/hostedtoolcrev-parse /usr/bin/wc 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 _test.go s git rev-�� --show-toplevel git /usr/bin/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 npx pret�� --check **/*.cjs 64/bin/go **/*.json --ignore-path ../../../.pretti/tmp/go-build3057861953/b396/_pkg_.a node (http block)
    • Triggering command: /usr/bin/gh gh api /orgs/test-owner/actions/secrets --jq .secrets[].name --show-toplevel ache/go/1.25.0/x64/pkg/tool/linux_amd64/compile (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 -unreachable=false /tmp/go-build2467091653/b144/vet.cfg 7091653/b314/vet.cfg (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha 64/pkg/tool/linu--show-toplevel git /usr/bin/git --show-toplevel 64/pkg/tool/linurev-parse /usr/bin/git git rev-�� --show-toplevel git /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/asm --show-toplevel ache/go/1.25.0/xrev-parse /usr/bin/git /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/asm (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha --show-toplevel git /usr/bin/git --show-toplevel git /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel git /usr/bin/git git (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 get --local 64/pkg/tool/linux_amd64/vet gpg.program ase,codename,allrev-parse (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha --show-toplevel git ache/node/24.14.0/x64/bin/node --show-toplevel x_amd64/vet /usr/bin/git gh _lab�� /repos/actions/checkout/git/ref/tags/v5 --jq /usr/bin/git --show-toplevel x_amd64/vet /usr/bin/git git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha -m Initial /usr/bin/git --show-toplevel git /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel git /usr/bin/git 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 (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha -bool -buildtags /usr/bin/git -errorsas -ifaceassert -nilfunc git rev-�� --show-toplevel -tests /usr/bin/git lowedTools (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel x_amd64/vet /usr/bin/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 -ignore_readdir_race -lname /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet -exec touch -c /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet -uns�� -unreachable=false /tmp/go-build2467091653/b226/vet.cfg 7091653/b303/vet.cfg (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha -t security /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/compile OUTPUT -d 168.63.129.16 /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/compile -o /tmp/go-build2467091653/b363/_pkg_.a -trimpath 7091653/b317/vet.cfg -p github.com/stretrev-parse -lang=go1.17 /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha --show-toplevel x_amd64/vet /usr/bin/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 s/^session\.save_path=\(.*;\)\?\(.*\)$/\2/p (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha --slice=azure-walinuxagent-logcollector.slice --scope /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet --property=Memorgit --property=CPUQurev-parse --property=Memor--show-toplevel /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet -ato�� -bool -buildtags 7091653/b309/vet.cfg -errorsas -ifaceassert -nilfunc /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha -t security /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet OUTPUT -d 168.63.129.16 /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet -uns�� -unreachable=false /tmp/go-build2467091653/b005/vet.cfg 7091653/b312/vet.cfg ACCEPT (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 --slice=azure-walinuxagent-logcollector.slice --scope /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet --property=Memorgit --property=CPUQurev-parse --property=Memor--show-toplevel /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet -ato�� -bool -buildtags 7091653/b306/vet.cfg -errorsas -ifaceassert -nilfunc /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha 64/pkg/tool/linu--show-toplevel git /home/REDACTED/.local/bin/bash --show-toplevel 64/pkg/tool/linurev-parse /usr/bin/git bash --no�� --noprofile git /usr/bin/git --show-toplevel 64/pkg/tool/linurev-parse /usr/bin/git git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha --show-toplevel git /usr/bin/git --show-toplevel git /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel du /usr/bin/git 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 se 7091653/b316/vet.cfg /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet -exec touch -c /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet -ato�� -bool -buildtags /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet -errorsas -ifaceassert -nilfunc /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha 64/pkg/tool/linu--show-toplevel git /home/REDACTED/work/_temp/uv-python-dir/bash --show-toplevel 64/pkg/tool/linurev-parse /usr/bin/git bash --no�� --noprofile git /usr/bin/git --show-toplevel 64/pkg/tool/linurev-parse /usr/bin/git git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha --show-toplevel git /usr/bin/git --show-toplevel git /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel git /usr/bin/git 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 s/^session\.save_handler=\(.*\)$/\1/p (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v0.1.2 --jq .object.sha 64/pkg/tool/linu--show-toplevel git /opt/hostedtoolcache/node/24.14.0/x64/bin/node --show-toplevel 64/pkg/tool/linurev-parse /usr/bin/gh node js/f�� k/_temp/uv-pytho--show-toplevel gh /usr/bin/git /repos/actions/cgit --jq /usr/bin/git git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v0.1.2 --jq .object.sha --show-toplevel git /usr/bin/git --show-toplevel git /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel sed /usr/bin/git git (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 --get-regexp .cfg 64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq .object.sha --show-toplevel git ache/node/24.14.0/x64/bin/node --show-toplevel (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq .object.sha --show-toplevel bash /usr/bin/git --noprofile git /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel git /usr/bin/git 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 --get-regexp .cfg 64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq .object.sha --show-toplevel git ache/node/24.14.0/x64/bin/node --show-toplevel (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq .object.sha --show-toplevel bash /usr/bin/git --noprofile git /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel git /usr/bin/git git (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/1/artifacts
    • Triggering command: /usr/bin/gh gh run download 1 --dir test-logs/run-1 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env 345277630/.github/workflows GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 1 --dir test-logs/run-1 git /usr/bin/git --show-toplevel svFghWGleN6uxv9Trev-parse /usr/bin/git git clon�� tructions-test-1582442059/.github/workflows /tmp/TestParseDefaultBranchFromLsRemoteWithRealGitmain_branch4145515942/002/work /usr/bin/git l go /usr/bin/git git (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12345/artifacts
    • Triggering command: /usr/bin/gh gh run download 12345 --dir test-logs/run-12345 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE R9/-4LzASpRV2zK6St_2P28/4-jKiyOZrev-parse env -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 12345 --dir test-logs/run-12345 git /usr/bin/git --show-toplevel e/git /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12346/artifacts
    • Triggering command: /usr/bin/gh gh run download 12346 --dir test-logs/run-12346 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env 2534181457/.github/workflows GO111MODULE n-dir/bash GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 12346 --dir test-logs/run-12346 git /opt/hostedtoolcache/node/24.14.0/x64/bin/node --show-toplevel e/git /usr/bin/gh node /tmp�� /tmp/TestHashConsistency_GoAndJavaScript2711131188/001/test-simple-frontmatter.md gh ache/node/24.14.0/x64/bin/node /repos/github/ghgit --jq /usr/bin/git git (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/2/artifacts
    • Triggering command: /usr/bin/gh gh run download 2 --dir test-logs/run-2 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env 345277630/.github/workflows GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 2 --dir test-logs/run-2 git /usr/bin/git tags/v6 ache/go/1.25.0/xrev-parse /usr/bin/git git init�� tructions-test-1582442059/.github/workflows --initial-branch=main trepo.git --show-toplevel go /usr/bin/git git (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/3/artifacts
    • Triggering command: /usr/bin/gh gh run download 3 --dir test-logs/run-3 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 3 --dir test-logs/run-3 git /usr/bin/git --show-toplevel e/git /usr/bin/git git rev-�� --show-toplevel l /usr/bin/git --show-toplevel go /usr/bin/git git (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/4/artifacts
    • Triggering command: /usr/bin/gh gh run download 4 --dir test-logs/run-4 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 4 --dir test-logs/run-4 git At,event,headBranch,headSha,displayTitle /ref/tags/v8 e/git /usr/bin/git node /tmp�� /tmp/TestHashConsistency_GoAndJavaScript2711131188/001/test-frontmatter-with-env-template-expresgit git /usr/bin/git --show-toplevel (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/5/artifacts
    • Triggering command: /usr/bin/gh gh run download 5 --dir test-logs/run-5 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env 3724671510/.github/workflows GO111MODULE ndor/bin/bash GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 5 --dir test-logs/run-5 git (http block)
  • https://api.github.com/repos/github/gh-aw/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path 181594972/001' 181594972/001' 64/bin/go GOINSECURE GOMOD GOMODCACHE node /opt�� prettier --check 64/bin/go **/*.ts **/*.json --ignore-path /bin/sh (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 GOWORK 64/bin/go /opt/hostedtoolc--auto -o /tmp/go-build147--detach -trimpath 64/bin/go -p main -lang=go1.25 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 6 GOMOD GOMODCACHE 95/ONlqAOqvsuUuntLFpp_r/Fshgtaf5g2phTYrb_URL env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (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 --show-toplevel -tests /usr/bin/git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v0.47.4 --jq .object.sha --show-toplevel git /usr/bin/gh --show-toplevel ache/go/1.25.0/xrev-parse /usr/bin/git gh api /repos/actions/checkout/git/ref/tags/v5 --jq /usr/bin/git --show-toplevel ache/go/1.25.0/xshow-ref /usr/bin/git git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v0.47.4 --jq .object.sha --show-toplevel git /usr/bin/git --show-toplevel git /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel git /usr/bin/git 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 (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha --show-toplevel 64/pkg/tool/linux_amd64/vet /usr/bin/git --local .cfg ache/go/1.25.0/x64/pkg/tool/linu--show-toplevel git rev-�� --show-toplevel ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet /usr/bin/git se 7091653/b104/vetjs/fuzz_sanitize_output_harness.cjs ache/go/1.25.0/x64/pkg/tool/linu--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha --show-toplevel ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet /usr/bin/git se 7091653/b214/vet-atomic ache/go/1.25.0/x-bool git rev-�� --show-toplevel ache/go/1.25.0/x-ifaceassert /usr/bin/git -t security /opt/hostedtoolc--show-toplevel git (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 --check **/*.cjs 64/bin/go **/*.json --ignore-path ../../../.pretti--pack_header=2,3 12LoK7c1ionw **/*�� --ignore-path node 64/bin/go run format:pkg-json 64/bin/go go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.2.3 --jq .object.sha ty-test.md ache/node/24.14.0/x64/bin/node /usr/bin/git ere mktemp /usr/bin/git git rev-�� ub/workflows git /usr/bin/git add origin /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 --check **/*.cjs 64/bin/go **/*.json --ignore-path ../../../.prettifor-each-ref find /var�� ! -name 64/bin/go -prune -type f go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq .object.sha --check scripts/**/*.js 64/bin/go .prettierignore GOWORK 64/bin/go /usr/bin/apt-con--auto shel�� APT_SOURCESDIR Dir::Etc::sourceparts/d 64/bin/go npx prettier --wgit bash 64/bin/go go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq .object.sha "prettier" --che-errorsas sh 64/bin/go "prettier" --wri/usr/lib/git-core/git iptables 64/bin/go 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
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v3.0.0 --jq .object.sha --check **/*.cjs 64/bin/go **/*.json --ignore-path ../../../.pretti-test.paniconexit0 /etc/cron.daily/-test.v=true git bash sh 64/bin/go npx prettier --wgit bash 64/bin/go go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v3.0.0 --jq .object.sha --show-toplevel /opt/hostedtoolcache/go/1.25.0/x-d x_amd64/vet -bool -buildtags /usr/bin/git x_amd64/vet \n : git /usr/bin/git --show-toplevel -tests /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 (http block)
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha --show-toplevel 64/pkg/tool/linux_amd64/vet /usr/bin/git --local user.name ache/go/1.25.0/x64/pkg/tool/linu--show-toplevel git rev-�� --show-toplevel ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet /usr/bin/git se 7091653/b141/vetjs/fuzz_sanitize_output_harness.cjs .cfg git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha --show-toplevel ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet /usr/bin/git se 7091653/b216/vet-atomic ache/go/1.25.0/x-bool git rev-�� --show-toplevel ache/go/1.25.0/x-ifaceassert /usr/bin/git --noprofile (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 go env y_only_defaults_repo7400221/001 GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion --show-toplevel (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 -importcfg /tmp/go-build3057861953/b413/importcfg -pack /home/REDACTED/work/gh-aw/gh-aw/pkg/gitutil/gitutil.go /home/REDACTED/work/gh-aw/gh-aw/pkg/gitutil/gitutil_test.go /opt�� prettier --check 64/bin/go **/*.ts **/*.json --ignore-path go (http block)
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo 64/bin/go GOINSECURE GOMOD GOMODCACHE node /opt�� prettier --check 64/bin/go **/*.ts **/*.json --ignore-path go (http block)
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo /usr/bin/git /tmp/go-build305iptables -trimpath /opt/hostedtoolc-t git rev-�� --show-toplevel /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/link /usr/bin/git /tmp/go-build305/usr/lib/git-core/git -importcfg /usr/bin/git git (http block)
  • https://api.github.com/repos/owner/repo/contents/file.md
    • Triggering command: /tmp/go-build3057861953/b396/cli.test /tmp/go-build3057861953/b396/cli.test -test.testlogfile=/tmp/go-build3057861953/b396/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE node (http block)
    • Triggering command: /tmp/go-build1623146796/b373/cli.test /tmp/go-build1623146796/b373/cli.test -test.testlogfile=/tmp/go-build1623146796/b373/testlog.txt -test.paniconexit0 -test.timeout=2m0s rev-�� --show-toplevel go /usr/bin/git Qwjfc586n GO111MODULE /usr/local/sbin/--show-toplevel git rev-�� --show-toplevel bash /usr/bin/git k/gh-aw/gh-aw/.ggit stmain.go /usr/bin/git 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 sh -c npx prettier --cGOINSECURE GOPROXY 64/bin/go GOSUMDB GOWORK run-script/lib/n-bool node (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 --show-toplevel GOPROXY ache/node/24.14.--show-toplevel git rev-�� e:]]*"\([^"]*\)".*/\1/p /usr/lib/git-core/git /usr/bin/git bility_SameInputgit --format=%(objecrev-parse /usr/bin/git git (http block)

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

…sing

- Replace O(n) sliceutil.Filter scans in GetActionPin/GetActionPinWithData/GetActionPinByRepo
  with O(1) map lookups using a pre-built per-repo index (cachedActionPinsByRepo)
  built alongside cachedActionPins in the sync.Once initializer
- Eliminate ~290 allocations/op and ~55 KB heap/op from action pin lookups
- Cache NewPermissionsParser result in validateWorkflowData: parse once, reuse
  across GitHub MCP toolset validation, id-token:write check, and agentic-workflows check
- Fix conditional logic: handle foundCompatible success case before fallback case

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/4dd0ddac-2adf-4ad2-b38b-207f9a31fcbb

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix regression in CompileMCPWorkflow performance perf: eliminate repeated O(n) action pin scans and redundant permissions parsing in MCP workflow compilation Apr 3, 2026
Copilot AI requested a review from pelikhan April 3, 2026 06:35
@github-actions github-actions bot mentioned this pull request Apr 3, 2026
@github-actions

This comment has been minimized.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 3, 2026

Hey @pelikhan 👋 — great performance work here! The benchmark-driven framing and clear before/after numbers make this a well-motivated change. A couple of things worth addressing before this lands:

  • No test coverage for the new O(1) indexgetActionPinsByRepo and cachedActionPinsByRepo are untested in isolation. There's no assertion that the per-repo sort invariant (version-descending) holds after sync.Once populates the map.

  • Subtle behaviour change in compiler.go — the original id-token check was guarded by if workflowData.Permissions != "", so parsing (and the warning) was skipped entirely on workflows with no permissions block. The refactored path always calls cachedPermissions.Get(PermissionIdToken) regardless. A unit test for validateWorkflowData with an empty Permissions string would confirm the warning is still suppressed in that case.

  • sortPinsByVersion may be dead code — the function no longer appears to be called from any public path removed by this PR. Consider removing it or adding a comment explaining why it's kept.

If you'd like a hand, here's a prompt for the coding agent:

In pkg/workflow/action_pins.go and pkg/workflow/compiler.go, address the following gaps introduced by the performance refactor in PR #24256:

1. Add a unit test for getActionPinsByRepo (or its public surface) in pkg/workflow/action_pins_test.go that verifies:
   - The per-repo map is populated correctly from the global pins list
   - Pins within each repo are sorted version-descending (latest first)
   - The sync.Once caching does not return stale data if called multiple times

2. Add a unit test for validateWorkflowData with an empty Permissions string, confirming the id-token warning is NOT emitted (parity with the pre-refactor behaviour).

3. Either remove sortPinsByVersion if it is no longer called anywhere, or add a comment explaining its intended use.

Run: go test -v -run "TestGetActionPinsByRepo|TestValidateWorkflowData" ./pkg/workflow/

Generated by Contribution Check · ● 2.2M ·

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[performance] Regression in CompileMCPWorkflow: +20.1% slower

2 participants