Skip to content

Batch PHP version fetches via GraphQL to stay within Worker subrequest limits#130

Merged
admdly merged 8 commits into
mainfrom
claude/release-data-subrequest-limits-po75dc
Jun 20, 2026
Merged

Batch PHP version fetches via GraphQL to stay within Worker subrequest limits#130
admdly merged 8 commits into
mainfrom
claude/release-data-subrequest-limits-po75dc

Conversation

@admdly

@admdly admdly commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

With 50+ releases, fetching composer.json individually for each release via the GitHub Contents API consumed more than 50 subrequests per Worker invocation, hitting Cloudflare's free-plan limit.

This replaces N individual subrequests with a single GitHub GraphQL batch query that retrieves all composer.json files in one round trip. Releases already stored in the KV cache reuse their cached PHP version so updates only fetch data for genuinely new releases, keeping total subrequests at ≤2 per invocation regardless of how many releases exist.

claude added 4 commits June 20, 2026 02:59
…equest limits

With 50+ releases, fetching composer.json individually for each release via
the GitHub Contents API consumed more than 50 subrequests per Worker invocation,
hitting Cloudflare's free-plan limit.

This replaces N individual subrequests with a single GitHub GraphQL batch
query that retrieves all composer.json files in one round trip. Releases already
stored in the KV cache reuse their cached PHP version so updates only fetch data
for genuinely new releases — keeping total subrequests at ≤2 per invocation
regardless of how many releases exist.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TNinmcp7f22H7ufvKozUeJ
Replaces individual GitHub Contents API calls (one per release) with a
single GraphQL batch request, eliminating the Cloudflare Workers
subrequest limit error (50 subrequests on free plan) that occurred when
processing 50+ releases.

The new implementation builds a single GraphQL query with per-release
field aliases and skips releases whose PHP version is already cached in
KV, meaning the worst case is 2 subrequests total (1 REST + 1 GraphQL)
regardless of release count.

Test mocks updated across all test files to provide a proper
@octokit/request.defaults stub so @octokit/graphql can initialise in
the Cloudflare workerd environment, and to mock @octokit/graphql
directly rather than stubbing fetch.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TNinmcp7f22H7ufvKozUeJ
- Add REPO_OWNER / REPO_NAME constants and thread them through the REST
  call and the GraphQL query string instead of four separate hardcoded
  "FOSSBilling" literals
- Collapse the intermediate `aliases` array in getBatchPhpVersions: the
  alias formula is now computed inline during the field-building pass and
  again during the result-reading pass, reducing allocations from 3
  arrays to 2 (fields + result map)
- Delete the exported getReleaseMinPhpVersion function and its companion
  GetReleaseMinPhpVersionResult interface — both were dead code after the
  batch GraphQL path replaced the per-release REST fetches
- Simplify createGraphQLImplementation in test/utils/mock-helpers.ts:
  iterate the matchAll iterator directly with for..of instead of
  spreading it into an intermediate array

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TNinmcp7f22H7ufvKozUeJ
Copilot AI review requested due to automatic review settings June 20, 2026 03:32
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 20, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
api d246b2b Commit Preview URL

Branch Preview URL
Jun 20 2026, 03:46 AM

Deleted alongside getReleaseMinPhpVersion, which was its only call site.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TNinmcp7f22H7ufvKozUeJ

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the Versions API v1 service to avoid Cloudflare Worker subrequest-limit issues by batching composer.json retrieval via a single GitHub GraphQL query, reusing cached PHP requirements where possible.

Changes:

  • Replace per-release contents REST calls with a single GraphQL batch query to fetch composer.json blobs for missing releases.
  • Reuse cached minimum_php_version values to keep subrequests bounded as release counts grow.
  • Add @octokit/graphql dependency and update test mocks/helpers to support GraphQL-based fetching.

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/services/versions/v1/index.ts Implements GraphQL batching and cache reuse for PHP requirement extraction.
package.json Adds @octokit/graphql runtime dependency.
package-lock.json Locks @octokit/graphql and related dependency tree updates.
test/utils/mock-helpers.ts Adds GraphQL mock generator + wires GraphQL into GitHub API test setup helper.
test/utils/test-types.ts Adds a GraphQL mock interface for tests.
test/services/versions/v1/index.test.ts Updates versions tests to use GraphQL mocks and new call-count expectations.
test/services/versions/v1/errors.test.ts Updates error-handling tests to simulate missing/malformed composer blobs via GraphQL.
test/services/versions/v1/middleware.test.ts Updates middleware tests to include GraphQL mocking.
test/services/stats/v1/index.test.ts Updates stats tests to provide GraphQL mocking via shared helper.
test/integration/versions/index.test.ts Updates integration tests to include GraphQL mocking.
test/integration/app.test.ts Updates full-app integration tests to include GraphQL mocking.
test/app/index.test.ts Updates app tests to provide GraphQL mock implementation.
wrangler.jsonc Minor JSONC formatting tweak in routes section.

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

Comment thread src/services/versions/v1/index.ts
Comment thread src/services/versions/v1/index.ts Outdated
Comment thread test/utils/test-types.ts
admdly and others added 3 commits June 20, 2026 04:39
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Name-derived aliases (v${tag.replace(/[^a-zA-Z0-9]/g, "_")}) can
collide for semver tags that differ only in separator characters
(e.g. 1.0.0-alpha.1 and 1.0.0-alpha-1 both produce v1_0_0_alpha_1),
which would cause one release's composer.json blob to overwrite another
in the response map.

Replacing with positional aliases r0, r1, r2... guarantees uniqueness
regardless of tag format and simplifies the alias derivation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TNinmcp7f22H7ufvKozUeJ
@admdly admdly changed the title fix: batch PHP version fetches via GraphQL to stay within Worker subrequest limits Batch PHP version fetches via GraphQL to stay within Worker subrequest limits Jun 20, 2026
@admdly admdly merged commit a2c5794 into main Jun 20, 2026
8 checks passed
@admdly admdly deleted the claude/release-data-subrequest-limits-po75dc branch June 20, 2026 03:50
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.

3 participants