Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .changeset/clever-lions-work.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
4 changes: 2 additions & 2 deletions .github/workflows/e2e-cleanups.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ name: Cleanup e2e instances
on:
workflow_dispatch:
schedule:
# run every 6 hours on every weekday
- cron: '0 */6 * * 1-5'
# run every 2 hours on every weekday
- cron: '0 */2 * * 1-5'
Comment on lines +5 to +6

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.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 12 \
  'concurrency:|cancel-in-progress|timeout-minutes|test:integration:cleanup|playwright test' \
  .github/workflows/e2e-cleanups.yml

Repository: clerk/javascript

Length of output: 1505


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- workflow ---'
cat -n .github/workflows/e2e-cleanups.yml

printf '%s\n' '--- workflow-level concurrency and cleanup references ---'
rg -n -C 4 \
  'e2e-cleanups|integration-tests|INTEGRATION_INSTANCE_KEYS|test:integration:cleanup|concurrency:|cancel-in-progress|TIMEOUT_MINUTES_NORMAL' \
  .github package.json pnpm-workspace.yaml 2>/dev/null || true

printf '%s\n' '--- repository-local cleanup locks ---'
rg -n -i -C 3 \
  'cleanup.*lock|lock.*cleanup|mutex|concurrency|cancel-in-progress' \
  .github scripts packages tests 2>/dev/null || true

Repository: clerk/javascript

Length of output: 40631


Add a concurrency group for cleanup runs.

The workflow has no concurrency control. GitHub Actions can start another scheduled or manually dispatched run while the first is active.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/e2e-cleanups.yml around lines 5 - 6, Add a concurrency
configuration to the workflow containing the “0 */2 * * 1-5” schedule, using a
stable group identifier shared by scheduled and manually dispatched runs so only
one cleanup run can execute at a time. Configure the group to cancel or
otherwise prevent overlapping runs according to the intended cleanup behavior.


permissions:
contents: read
Expand Down
6 changes: 3 additions & 3 deletions integration/cleanup/cleanup.setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ setup('cleanup instances ', async () => {
const { data: usersWithEmail } = await clerkClient.users.getUserList({
orderBy: '-created_at',
query: 'clerkcookie',
limit: 150,
limit: 500,
});

const { data: usersWithPhoneNumber } = await clerkClient.users.getUserList({
orderBy: '-created_at',
query: '55501',
limit: 150,
limit: 500,
Comment on lines +54 to +60

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.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 12 \
  'getUserList|getOrganizationList|totalCount|offset|limit: 500|delete' \
  integration/cleanup/cleanup.setup.ts

Repository: clerk/javascript

Length of output: 6439


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- cleanup.setup.ts (relevant sections) ---'
sed -n '1,145p' integration/cleanup/cleanup.setup.ts

printf '%s\n' '--- call sites and pagination symbols ---'
rg -n -C 6 'getUserList|getOrganizationList|offset|usersToDelete|orgsToDelete|limit' integration/cleanup/cleanup.setup.ts

printf '%s\n' '--- standalone structural check ---'
python3 - <<'PY'
from pathlib import Path
import re

path = Path("integration/cleanup/cleanup.setup.ts")
text = path.read_text()

calls = re.findall(
    r'(?P<api>getUserList|getOrganizationList)\s*\(\s*\{(?P<body>.*?)\}\s*\)',
    text,
    flags=re.S,
)
for api, body in calls:
    print(f"{api}: limit_500={bool(re.search(r'\\blimit\\s*:\\s*500\\b', body))}, "
          f"offset_present={bool(re.search(r'\\boffset\\s*:', body))}")

print("pagination_identifiers_present:",
      bool(re.search(r'\\b(offset|totalCount|lastPage|hasNextPage|nextPage)\\b', text)))
PY

Repository: clerk/javascript

Length of output: 8637


Add pagination to cleanup queries.

getUserList and getOrganizationList fetch only the first 500 results. If more than 500 stale objects match, later pages remain undeleted. Use offset to process all pages.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@integration/cleanup/cleanup.setup.ts` around lines 54 - 60, Update the
cleanup queries using clerkClient.users.getUserList and
clerkClient.organizations.getOrganizationList to paginate with offset,
repeatedly fetching batches of up to 500 until no results remain. Accumulate or
process every page so all matching stale users and organizations are deleted,
not just the first page.

});

// Deduplicate users by ID
Expand All @@ -76,7 +76,7 @@ setup('cleanup instances ', async () => {
let orgs: any[] = [];
try {
const { data: orgsData } = await clerkClient.organizations.getOrganizationList({
limit: 150,
limit: 500,
});
orgs = orgsData;
} catch (error) {
Expand Down
Loading