Repository navigation
fix(actions): reduce Draft queue pressure and retry GitHub reads #247
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
seonghobae
wants to merge
374
commits into
main
Choose a base branch
from
fix/actions-draft-queue-pressure-v1
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from 15 commits
Commits
Show all changes
374 commits
Select commit
Hold shift + click to select a range
9096c7a
test(commercial): pin one merge candidate per drain run
seonghobae 1ceca52
fix(commercial): bound each merge drain to one protected-main mutation
seonghobae 3c1f999
docs(changelog): record single-mutation merge drain
seonghobae 91de209
test(commercial): reject malformed review scalar authority
seonghobae b1f3ebd
test(commercial): isolate malformed review timestamp authority
seonghobae 7d63b2b
fix(commercial): reject non-string review timestamps
seonghobae cc3af56
test(commercial): reject later stale approval authority
seonghobae 06a12ca
fix(commercial): preserve stale approval chronology
seonghobae cbf2183
docs(changelog): record review authority repairs
seonghobae 8feede2
test(commercial): preserve review tie ordering
seonghobae b0ef942
fix(commercial): preserve equal-time review order
seonghobae 4f37fd7
test(commercial): reject non-canonical review timestamps
seonghobae 8757cbe
fix(commercial): reject non-canonical review timestamps
seonghobae eee913b
test(commercial): reject impossible review calendar timestamps
seonghobae 125c44a
fix(commercial): reject impossible review calendar timestamps
seonghobae e90868d
test(commercial): reject noncanonical status timestamps
seonghobae 81292d9
fix(commercial): require canonical status timestamps
seonghobae e375ec8
docs(changelog): record canonical review and status timestamps
seonghobae 101d736
test(commercial): reject coerced review identity authority
seonghobae db39ce3
fix(commercial): reject coerced review identity authority
seonghobae 48f5c71
docs(changelog): record review identity provenance repair
seonghobae 3a15a2c
test(commercial): reject malformed status identity scalars
seonghobae f3a76e4
test(commercial): reject malformed workflow identity scalars
seonghobae a30b309
test(commercial): reject malformed PR authority scalars
seonghobae bfece56
fix(commercial): preserve merge-authority scalar provenance
seonghobae 3cccee4
docs(changelog): record merge-authority scalar provenance
seonghobae 4ee8256
test(commercial): reject coerced live branch SHA authority
seonghobae e45ae29
fix(commercial): preserve live branch SHA scalar authority
seonghobae d47e3eb
docs(changelog): record live branch SHA provenance hardening
seonghobae 1035c2f
test(commercial-readiness): align invalid status blocker contract
seonghobae 22e5fc9
test(ci): align merge compatibility ready-state contract
seonghobae 4c52a07
test(commercial): reject malformed PR base SHA authority
seonghobae 5702ae2
fix(commercial): validate PR base SHA provenance
seonghobae 6661a82
docs(changelog): record PR base SHA provenance repair
seonghobae 838f1cd
test(commercial): require live protected-branch authority before merge
seonghobae cf4ea4a
fix(commercial): require protected default branch before merge
seonghobae 366bb08
docs(changelog): record protected branch merge authority
seonghobae eb801ca
test(commercial-readiness): bind compare base provenance
seonghobae e69e075
fix(commercial-readiness): bind compare response provenance
seonghobae cd0f9aa
test(commercial-readiness): cover compare provenance edges
seonghobae 23a8c00
docs(changelog): record compare provenance fence
seonghobae cc8f50f
test(commercial): reject self-review merge authority
seonghobae 5fd0de6
fix(commercial): reject pull request self-review authority
seonghobae 52ebaa3
docs(changelog): record independent review authority
seonghobae c361fb4
test(commercial): reject padded self-review identity
seonghobae a0b826f
test(commercial): reject unverifiable PR author identity
seonghobae 52f7027
fix(commercial): fail closed on review identity canonicality
seonghobae 6308261
docs(changelog): record review identity canonicality
seonghobae 6d537f6
test(commercial-readiness): refresh review provenance fixture
seonghobae e14e88c
test(commercial-readiness): avoid dynamic regex in docstring contract
seonghobae ee4f3e0
chore(commercial): expose exact formatter diff
seonghobae a318b54
chore(commercial): restore formatter gate after probe
seonghobae a7822a4
chore(commercial): expose current formatter diff
seonghobae 2904540
chore(commercial): restore formatter gate after diagnostic
seonghobae c8e124d
fix(commercial): restore full formatter coverage
seonghobae 26a0ccc
test(commercial): expose exact Prettier repair delta
seonghobae ed61b75
chore(commercial): restore canonical formatter gate
seonghobae 80c48ce
style(commercial): apply hosted Prettier delta
seonghobae 11d155e
test(commercial): require canonical pull-request head sha
seonghobae 8282391
fix(commercial): require canonical pull-request head sha
seonghobae 6f3014e
docs(changelog): record canonical merge head authority
seonghobae d206f31
test(commercial): reject recanonicalized snapshot SHA evidence
seonghobae e19f6a3
fix(commercial): require canonical snapshot SHA evidence
seonghobae 2529c63
docs(changelog): record snapshot SHA canonicality repair
seonghobae 53ed0d9
test(commercial): reject uppercase Git SHA aliases
seonghobae deaa5d8
fix(commercial): require canonical lowercase Git SHAs
seonghobae 86e529f
docs(changelog): record canonical Git SHA collection boundary
seonghobae 2ba9b75
test(commercial): reject padded review authority at final gate
seonghobae 977b740
fix(commercial): reject recanonicalized review identity at final gate
seonghobae 31f2768
docs(changelog): record canonical final review identity boundary
seonghobae 7be88d6
style(changelog): restore final newline
seonghobae e1eb072
test(commercial): reject coerced workflow attempts
seonghobae 7bbca25
fix(commercial): preserve workflow attempt scalar provenance
seonghobae f495600
docs(changelog): record workflow attempt provenance repair
seonghobae 267742a
test(commercial): reject recanonicalized default-branch SHA evidence
seonghobae 7470518
fix(commercial): preserve canonical default-branch SHA authority
seonghobae aeaa835
docs(changelog): record canonical default-branch SHA authority
seonghobae 5e78a35
test(commercial): reject recanonicalized merge receipt SHA
seonghobae 05b1f58
fix(commercial): preserve canonical merge receipt SHA
seonghobae caf9afe
docs(changelog): record canonical merge receipt SHA
seonghobae 4e313c7
test(commercial): reject case-variant reviewer aliases
seonghobae f352911
fix(commercial): fail closed on reviewer case aliases
seonghobae 2f28401
test(commercial): reject duplicate merge check evidence
seonghobae ff1e121
fix(commercial): fail closed on duplicate check evidence
seonghobae 1f4125c
test(commercial): retain merge commit in drain receipt
seonghobae 202c6d3
fix(commercial): retain merge commit in drain receipt
seonghobae de4a5ed
docs(changelog): record merge receipt provenance repairs
seonghobae c6316f3
test(commercial): align merge-drain fixture with receipt provenance
seonghobae 58579c0
test(commercial): fail closed on malformed merge mutation evidence
seonghobae ad2c9d3
fix(commercial): validate merge mutation evidence at drain boundary
seonghobae f11e014
test(commercial): reject duplicate status identity evidence
seonghobae 387874a
fix(commercial): reject duplicate status identity evidence
seonghobae b5f5a2b
docs(changelog): record status identity fail-closed repair
seonghobae 535eb6e
test(commercial): taint cross-context duplicate status identity
seonghobae 3ad32fa
fix(commercial): taint duplicate status identity before provenance re…
seonghobae c18c89f
docs(changelog): record pre-provenance status identity taint
seonghobae d25644b
test(commercial): reject duplicate merge-drain PR identity
seonghobae 62d317e
fix(commercial): fail closed on duplicate drain identity
seonghobae 2590fc2
docs(changelog): record duplicate drain identity repair
seonghobae 4de28fc
ci(readiness): repair hosted format RED
seonghobae 5cbb900
style(readiness): satisfy exact-head format gate
github-actions[bot] 9898bef
ci(commercial-readiness): repair exact formatting failure
seonghobae 81e4a7c
ci(commercial-readiness): remove completed repair writer
seonghobae 640b78d
fix(security): pin qs 6.16.0 owner resolution
seonghobae 24151c1
ci(security): regenerate qs lock with pnpm 10.15.0
seonghobae aab0dac
fix(ci): align inherited AppGuardrail workflow formatting
seonghobae 5dc01b6
fix(security): regenerate qs 6.16.0 lock resolution
github-actions[bot] 46e2f08
ci(security): reacquire exact-head gates after lockfile writer
seonghobae 41e0e0f
docs(security): record qs dependency repair
seonghobae 30303f2
test(security): preserve AppGuardrail markdown scope
seonghobae 15eb89c
fix(security): restore AppGuardrail markdown scope
seonghobae 74fea54
test(commercial-readiness): bound compare payload evidence
seonghobae 6a2d8d2
fix(commercial-readiness): bound compare payload
seonghobae d3ebe1b
ci(security): regenerate patched shared dependency graph
seonghobae 793d102
ci(security): verify regenerated dependency graph structurally
seonghobae 4aed8e6
ci(security): provision canonical test database
seonghobae 70d8d83
fix(security): upgrade shared vulnerable dependencies
github-actions[bot] a9db47d
docs(security): record patched shared dependency floors
seonghobae 15c4be1
ci(commercial-readiness): bridge package verification cycle
seonghobae 99127af
fix(commercial-readiness): adopt bounded compare evidence
github-actions[bot] cba64f2
docs(changelog): record bounded Compare contract
seonghobae 331eaff
test(commercial-readiness): reproduce per-trigger path-ignore gap
seonghobae a3065b2
fix(commercial-readiness): validate path-ignore per trigger
seonghobae 34dae7a
docs(changelog): distinguish Next minimum from lock resolution
seonghobae 2e773d8
test(commercial-readiness): scope path-ignore entries to list
seonghobae 97fd017
fix(changelog): restore canonical trailing newline
seonghobae 9d7bfdb
fix(format): cover current package repair paths
seonghobae dc4033c
fix(format): canonicalize AppGuardrail contract test
seonghobae b06c6e8
chore(ci): add one-shot PR249 formatter repair
seonghobae 5a950dc
fix(ci): canonicalize PR249 formatter targets
github-actions[bot] bb7c57c
test(quality): add Commercial Readiness docstring RED gate
seonghobae 3090de5
chore(ci): add one-shot Commercial Readiness docstring RED writer
seonghobae ddc385b
test(quality): establish Commercial Readiness docstring RED
github-actions[bot] 5a2a547
chore(ci): repair Commercial Readiness docstrings on exact head
seonghobae bc67198
fix(ci): bootstrap pnpm after Node setup in PR249 writer
seonghobae f838818
fix(ci): preserve exact PR249 docstring repair intent
seonghobae a8e3666
docs(quality): reach 100% Commercial Readiness docstrings
github-actions[bot] 8bd71d0
test(quality): reject filler Commercial Readiness docstrings
seonghobae 1a0e079
test(quality): enforce explanatory Commercial Readiness docstrings
seonghobae cf279b1
ci: canonicalize PR249 docstring gate formatting
seonghobae 3738be1
fix(ci): format Commercial Readiness docstring gate
github-actions[bot] 09d1430
docs: record substantive Commercial Readiness docstrings
seonghobae 707768e
test(readiness): preserve size classification on cancel failure
seonghobae 8aa2058
ci(readiness): prove stream-cancel size-classification RED
seonghobae d273752
test(readiness): hand off bounded page-size regression
seonghobae 18982ac
ci(readiness): prove canonical response-bound REDs
seonghobae 93f3ab2
ci(readiness): repair bounded response handling
seonghobae 1a89648
ci(readiness): keep pagination repair contract-documented
seonghobae f95c250
test(readiness): align compare provenance fixture
seonghobae 1e807b1
fix(readiness): preserve bounded GitHub response evidence
github-actions[bot] 2b687bc
test(readiness): expose scalar fixture blockers
seonghobae f18c9ce
test(readiness): run scalar provenance RED
seonghobae 584a003
test(readiness): isolate PR scalar blockers
seonghobae 439f6a8
chore(readiness): retire scalar provenance verifier
seonghobae bd95e17
test(readiness): prove canonical status pagination timestamps
seonghobae 17df1f5
ci(readiness): isolate status pagination fixture RED
seonghobae 033b355
test(readiness): canonicalize status pagination timestamps
seonghobae d3c550b
chore(readiness): retire status pagination verifier
seonghobae 287cfed
ci(readiness): prove changelog preservation RED
seonghobae a9d25b9
docs(changelog): restore protected unreleased history
seonghobae d88773b
chore(readiness): retire changelog preservation verifier
seonghobae 3840d91
test(readiness): prove merge compatibility job-bound retry evidence
seonghobae b4e8838
ci(readiness): isolate merge retry scope RED
seonghobae b3c2e34
test(readiness): bound merge compatibility retry evidence
seonghobae c3db1ce
chore(readiness): retire CI retry scope verifier
seonghobae 6c614b4
test(readiness): prove drain job-level condition authority
seonghobae f82dc0c
ci(readiness): isolate drain condition RED
seonghobae 1eb6240
test(readiness): bind drain authority to job-level condition
seonghobae 578cb1b
chore(readiness): retire drain condition verifier
seonghobae e47745f
test(readiness): prove legacy v1 snapshot compatibility
seonghobae f67dd48
ci(readiness): isolate v1 snapshot compatibility RED
seonghobae 01abf95
fix(readiness): preserve legacy v1 review binding semantics
seonghobae ac92b7e
chore(readiness): retire v1 snapshot verifier
seonghobae 272ad3c
test(readiness): prove workflow author provenance RED
seonghobae fd3b1ac
ci(readiness): isolate workflow author provenance RED
seonghobae 281593e
test(readiness): bind workflow fixture author provenance
seonghobae 24c8527
test(readiness): bind workflow scalar author provenance
seonghobae 28765da
chore(readiness): retire workflow author verifier
seonghobae 14a53fd
test(readiness): reproduce exact pagination item limit
seonghobae 11edd03
chore(readiness): run bounded pagination repair
seonghobae 337dc74
test(readiness): capture pagination boundary diagnostics
seonghobae a99ca4c
test(readiness): correct pagination boundary oracle
seonghobae 7d3a6b8
fix(readiness): permit pagination limit confirmation
8accd30
test(readiness): cover bounded workflow-run pagination fallback
seonghobae d849070
ci(readiness): verify bounded workflow-run fallback
seonghobae 74c4b85
ci(readiness): repair bounded workflow-run fallback
seonghobae 42ece29
ci(readiness): format workflow-run pagination repair
seonghobae 2fb04b6
ci(readiness): install formatter before repair normalization
seonghobae d751877
fix(readiness): bound workflow-run response pagination
2357eec
chore(readiness): retire completed response verifier
seonghobae 1df5927
test(readiness): require oversized response cleanup
seonghobae 0a69184
test(readiness): verify declared response cleanup red
seonghobae 3fce2d1
test(readiness): preserve declared-size classification
seonghobae 0f5ee89
fix(readiness): repair declared response cleanup
seonghobae 386c1f6
fix(readiness): repair writer source matching
seonghobae 03b65cf
fix(readiness): cancel declared oversized responses
github-actions[bot] ac5921e
docs(readiness): stage declared response changelog
seonghobae 484e399
docs(readiness): record declared response cleanup
github-actions[bot] 0553086
test(commercial): reproduce multi-step response fallback
seonghobae d32bee9
ci(commercial): verify multi-step response fallback RED
seonghobae 0ae49bf
ci(commercial): verify full multi-step fallback candidate
seonghobae b8dbac8
ci(commercial): stage bounded response repair writer
seonghobae b2439bc
ci(commercial): normalize and publish source-only repair
seonghobae 26a886a
fix(commercial): halve oversized GitHub pages to bounded floor
26978e0
ci(commercial): retire response repair writer
seonghobae 6a0dbf5
test(commercial): cover multi-step workflow response fallback
seonghobae e19ae00
ci(commercial): verify generic and workflow response fallback
seonghobae 48087da
ci(commercial): retire response verifier
seonghobae dc8609f
test(commercial): expose review tail pagination drift
seonghobae 2117e1b
fix(commercial-readiness): confirm every authoritative page
seonghobae 0641bae
test(commercial-readiness): reject workflow tail drift
seonghobae 7dbc78c
fix(commercial-readiness): revalidate every workflow page
seonghobae 1b9a2eb
test(commercial-readiness): expose snapshot collection ceiling mismatch
seonghobae 8ecfa9a
fix(commercial-readiness): align snapshot schema with collector ceiling
seonghobae 794e206
test(commercial-readiness): format snapshot ceiling regression
seonghobae 3ca23be
style(commercial-readiness): restore schema final newline
seonghobae 2b6db1f
test(readiness): reject drifting review-thread pages
seonghobae 78a2565
fix(readiness): stabilize review-thread traversal
seonghobae 64f5a62
test(readiness): cover stable review-thread replay
seonghobae f2cee0e
test(readiness): use canonical review-thread blocker
seonghobae 1cfea9d
test(readiness): align reduced evidence ceiling
seonghobae 236ced3
fix(readiness): preserve complete workflow status evidence
seonghobae 6680275
test(commercial-readiness): reproduce locale-dependent gap order
seonghobae 1feadf1
fix(commercial-readiness): make gap ordering locale-independent
seonghobae fdebd3b
test(commercial-readiness): keep locale probe minimal
seonghobae 6294434
test(commercial-readiness): reproduce locale-dependent evidence order
seonghobae d44bbed
fix(commercial-readiness): make GitHub evidence ordering locale-indep…
seonghobae 72217f3
ci: repair #247 exact-head formatting
seonghobae 11780c1
ci: retire stalled PR 247 formatter writer
seonghobae a48f6de
style(commercial-readiness): canonicalize GitHub client
seonghobae 7dd329b
test(commercial-readiness): keep compare files out of snapshot reads
seonghobae acc1799
chore(commercial-readiness): remove duplicate compare-bound test
seonghobae 2a81eda
test(deps): require reviewed esbuild install authority
seonghobae df8616b
test(deps): bind esbuild authority to exact frozen version
seonghobae 484652e
revert(deps): preserve canonical build-script owner
seonghobae 34ba210
merge(commercial-readiness): compose security and bounded-evidence ow…
seonghobae 759b7e9
test(commercial-readiness): reject malformed UTF-8 evidence
seonghobae 3128922
ci(commercial-readiness): add bounded UTF-8 evidence repair
seonghobae 83a3720
fix(commercial-readiness): reject malformed UTF-8 evidence
seonghobae c99a131
test(commercial-readiness): verify strict UTF-8 evidence boundary
seonghobae 96dfbe6
chore(actions): retire branch-only verification workflow
seonghobae 153149a
test(commercial-readiness): verify production docstring repair
seonghobae a02d5e7
ci(commercial-readiness): repair missing production docstring
seonghobae c6961c7
fix(commercial-readiness): document scalar authority boundary
github-actions[bot] 835d6d1
ci(commercial-readiness): bind exact docstring repair verifier
seonghobae 64a4428
test(commercial-readiness): retire docstring verifier after green
seonghobae 5d4665b
test(commercial-readiness): verify live response-bounded snapshot col…
seonghobae c84d3a8
fix(ci): fetch commercial readiness ancestry for verifier
seonghobae c0b30d1
test(ci): retire response-bounds verifier after green
seonghobae 8e6905a
fix(security): refresh patched Multer graph
seonghobae File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
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
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
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
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
92 changes: 92 additions & 0 deletions
92
packages/commercial-readiness/src/github-client-read-retry.test.mjs
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| import assert from 'node:assert/strict'; | ||
| import { describe, it } from 'node:test'; | ||
| import { GitHubApiClient } from './github-client.mjs'; | ||
|
|
||
| function jsonResponse(value, status) { | ||
| const body = JSON.stringify(value); | ||
| return new Response(body, { | ||
| status, | ||
| headers: { | ||
| 'content-type': 'application/json', | ||
| 'content-length': String(Buffer.byteLength(body)), | ||
| }, | ||
| }); | ||
| } | ||
|
|
||
| describe('GitHubApiClient transient read retry', () => { | ||
| it('retries only bounded transient GET failures and returns the first successful response', async () => { | ||
| const statuses = [504, 502, 200]; | ||
| const calls = []; | ||
| const client = new GitHubApiClient({ | ||
| token: 'token', | ||
| fetchImpl: async (_url, options) => { | ||
| calls.push(options.method); | ||
| const status = statuses.shift(); | ||
| return jsonResponse( | ||
| status === 200 ? { ok: true } : { message: 'must-not-escape' }, | ||
| status, | ||
| ); | ||
| }, | ||
| }); | ||
|
|
||
| assert.deepEqual(await client.requestJson('/repos/o/r'), { ok: true }); | ||
| assert.deepEqual(calls, ['GET', 'GET', 'GET']); | ||
| }); | ||
|
|
||
| it('stops after three transient GET attempts and preserves the generic status boundary', async () => { | ||
| let calls = 0; | ||
| const client = new GitHubApiClient({ | ||
| token: 'token', | ||
| fetchImpl: async () => { | ||
| calls += 1; | ||
| return jsonResponse({ secret: 'must-not-escape' }, 503); | ||
| }, | ||
| }); | ||
|
|
||
| await assert.rejects( | ||
| () => client.requestJson('/repos/o/r/actions/runs'), | ||
| new Error('GitHub API request failed with status 503'), | ||
| ); | ||
| assert.equal(calls, 3); | ||
| }); | ||
|
|
||
| it('never replays mutation requests after a transient server failure', async () => { | ||
| let calls = 0; | ||
| const client = new GitHubApiClient({ | ||
| token: 'token', | ||
| fetchImpl: async () => { | ||
| calls += 1; | ||
| return jsonResponse({ secret: 'must-not-escape' }, 503); | ||
| }, | ||
| }); | ||
|
|
||
| await assert.rejects( | ||
| () => | ||
| client.requestJson('/repos/o/r/issues/1', { | ||
| method: 'PATCH', | ||
| body: { state: 'closed' }, | ||
| }), | ||
| new Error('GitHub API request failed with status 503'), | ||
| ); | ||
| assert.equal(calls, 1); | ||
| }); | ||
|
|
||
| it('does not retry non-transient client or server statuses', async () => { | ||
| for (const status of [400, 401, 403, 404, 409, 422, 429, 501]) { | ||
| let calls = 0; | ||
| const client = new GitHubApiClient({ | ||
| token: 'token', | ||
| fetchImpl: async () => { | ||
| calls += 1; | ||
| return jsonResponse({ message: 'must-not-escape' }, status); | ||
| }, | ||
| }); | ||
|
|
||
| await assert.rejects( | ||
| () => client.requestJson('/repos/o/r'), | ||
| new Error(`GitHub API request failed with status ${status}`), | ||
| ); | ||
| assert.equal(calls, 1); | ||
| } | ||
| }); | ||
| }); | ||
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
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
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
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.