Bump to next prerelease#44
Conversation
|
Warning Review limit reached
More reviews will be available in 54 minutes and 18 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughThis PR adds a complete ChangesPrerelease version bump feature
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
src/__tests__/bump-prerelease.test.ts (1)
17-27: ⚡ Quick winReplace repeated
as anyin execa mocks with typed mock results (optional)The file disables
@typescript-eslint/no-explicit-anyat the top, so the current CI failure is unlikely to be from that rule; still, the repeatedPromise.resolve({ ... } as any)casts reduce type safety—centralizing them behind a typed helper keeps the mocks honest.Suggested pattern
import { runBumpPrerelease } from '../bump-prerelease'; import { execa } from 'execa'; @@ const mockedExeca = execa as jest.MockedFunction<typeof execa>; +type ExecaResult = Awaited<ReturnType<typeof execa>>; +const ok = (stdout = ''): ExecaResult => ({ stdout } as unknown as ExecaResult); @@ - return Promise.resolve({ stdout: 'origin' } as any); + return Promise.resolve(ok('origin')); @@ - return Promise.resolve({ stdout: '' } as any); + return Promise.resolve(ok('')); @@ - return Promise.resolve({} as any); + return Promise.resolve(ok());🤖 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 `@src/__tests__/bump-prerelease.test.ts` around lines 17 - 27, The execa mocks in mockedExeca.mockImplementation use repeated Promise.resolve({ ... } as any); replace those casts with a small typed helper (e.g., typedResolve<T>(value: T): Promise<ReturnType<typeof mockedExeca>>) or a helper that returns a properly typed mock result so each branch (the 'git remote', 'git tag -l', and default branches inside mockedExeca.mockImplementation) returns a correctly typed object instead of using as any; update the branches checking args?.[0] === 'remote', args?.[0] === 'tag' && args?.[1] === '-l', and args?.[0] === 'rev-parse' to use that helper.
🤖 Prompt for all review comments with 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.
Inline comments:
In `@src/bump-prerelease.ts`:
- Around line 74-80: tagExists currently calls git rev-parse on the plain tag
which can resolve non-tag refs; change the execa call in function tagExists to
resolve the tag under refs/tags by calling git rev-parse refs/tags/${tag} (still
passing the cwd option and preserving the existing try/catch and boolean return
behavior) so the check only succeeds for actual annotated/created tags.
- Around line 34-37: The tagExists helper in src/bump-prerelease.ts currently
uses a general git rev-parse which can return true for non-tag refs; update
tagExists to verify the actual tag ref by running git show-ref --tags --verify
--quiet refs/tags/<tag> (or the equivalent API call) and return true only on a
successful exit code, false on not-found, and rethrow other errors (preserving
original error as cause if present); reference the tagExists function name when
making this change so callers keep behavior but no longer get false positives
for branches or other refs with the same name.
---
Nitpick comments:
In `@src/__tests__/bump-prerelease.test.ts`:
- Around line 17-27: The execa mocks in mockedExeca.mockImplementation use
repeated Promise.resolve({ ... } as any); replace those casts with a small typed
helper (e.g., typedResolve<T>(value: T): Promise<ReturnType<typeof
mockedExeca>>) or a helper that returns a properly typed mock result so each
branch (the 'git remote', 'git tag -l', and default branches inside
mockedExeca.mockImplementation) returns a correctly typed object instead of
using as any; update the branches checking args?.[0] === 'remote', args?.[0] ===
'tag' && args?.[1] === '-l', and args?.[0] === 'rev-parse' to use that helper.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: af816658-65a4-4344-abd8-796e310480e4
📒 Files selected for processing (5)
.husky/commit-msgREADME.mdsrc/__tests__/bump-prerelease.test.tssrc/bump-prerelease.tssrc/cli.ts
| } catch (error) { | ||
| if (error instanceof Error) { | ||
| throw new Error(`Failed to determine upstream remote: ${error.message}`); | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="src/bump-prerelease.ts"
if [ ! -f "$FILE" ]; then
echo "Missing $FILE"
exit 1
fi
echo "== File head =="
head -n 120 "$FILE" | sed -n '1,120p'
echo
echo "== Lines 1-120 (with numbers) =="
nl -ba "$FILE" | sed -n '1,140p'
echo
echo "== Lines 30-90 (with numbers) =="
nl -ba "$FILE" | sed -n '30,90p'
echo
echo "== Lines 90-140 (with numbers) =="
nl -ba "$FILE" | sed -n '90,170p'
echo
echo "== Search for 'new Error(`Failed' in file =="
rg -n "new Error\\(`Failed" "$FILE" || true
echo
echo "== Search for rethrow patterns in file =="
rg -n "throw new Error\\(" "$FILE" || trueRepository: patternfly/patternfly-cli
Length of output: 3904
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="src/bump-prerelease.ts"
if [ ! -f "$FILE" ]; then
echo "Missing $FILE"
exit 1
fi
echo "== rg for catch blocks =="
rg -n "catch \\(error\\)" "$FILE" || true
echo
echo "== Show 25 lines after each 'catch (error)' =="
# Use awk to print with line numbers since nl isn't available
awk '
/catch \(error\)/ {print "---- match at line " NR; start=NR; next}
start && NR>start && NR<=start+25 {print NR ":" $0}
start && NR>start+25 {start=0}
' "$FILE"
echo
echo "== Find all 'new Error(`Failed' occurrences =="
rg -n "new Error\\(\\`Failed" "$FILE" || true
echo
echo "== Check each throw new Error(...) line and whether it has { cause: error } =="
awk '
/throw new Error\(/ {
line=NR;
print "---- throw at line " NR;
for(i=NR;i<=NR+3;i++) if(getline l<0) break; # no-op
}
' "$FILE" >/dev/null 2>&1 || true
# Simpler: print the exact lines containing throw new Error(...) and nearby
rg -n -C 2 "throw new Error\\(" "$FILE"
echo
echo "== tagExists definition =="
rg -n "async function tagExists" "$FILE" -n
# Print function block (up to closing brace) with a small window
rg -n -C 3 "async function tagExists\\(" "$FILE"
echo
echo "== Usages of tagExists =="
rg -n "tagExists\\(" "$FILE" || trueRepository: patternfly/patternfly-cli
Length of output: 3428
Harden tagExists to check only actual tags
src/bump-prerelease.tsalready preserves error context in the rethrows (both catch blocks include{ cause: error }), so no change is needed there.tagExistsusesgit rev-parse <tag>, which can return true for non-tag refs (e.g., a branch) with the same name; verifyrefs/tags/<tag>instead (e.g.,git show-ref --tags --verify --quiet refs/tags/<tag>) to avoid false positives.
🧰 Tools
🪛 ESLint
[error] 36-36: There is no cause attached to the symptom error being thrown.
(preserve-caught-error)
🤖 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 `@src/bump-prerelease.ts` around lines 34 - 37, The tagExists helper in
src/bump-prerelease.ts currently uses a general git rev-parse which can return
true for non-tag refs; update tagExists to verify the actual tag ref by running
git show-ref --tags --verify --quiet refs/tags/<tag> (or the equivalent API
call) and return true only on a successful exit code, false on not-found, and
rethrow other errors (preserving original error as cause if present); reference
the tagExists function name when making this change so callers keep behavior but
no longer get false positives for branches or other refs with the same name.
| async function tagExists(tag: string, cwd: string): Promise<boolean> { | ||
| try { | ||
| await execa('git', ['rev-parse', tag], { cwd }); | ||
| return true; | ||
| } catch { | ||
| return false; | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate and print the relevant section of bump-prerelease.ts
FILE="src/bump-prerelease.ts"
if [ ! -f "$FILE" ]; then
echo "Missing $FILE"
exit 1
fi
echo "== Snippet around tagExists =="
nl -ba "$FILE" | sed -n '50,110p'
echo "== tagExists usages =="
rg -n "tagExists\(" "$FILE"Repository: patternfly/patternfly-cli
Length of output: 162
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="src/bump-prerelease.ts"
echo "== Checking file =="
ls -la "$FILE" || { echo "Missing $FILE"; exit 1; }
echo "== File length (lines) =="
wc -l "$FILE"
echo "== Snippet around tagExists (lines 60-95) =="
python3 - <<'PY'
import itertools
path="src/bump-prerelease.ts"
start,end=60,95
with open(path,'r',encoding='utf-8') as f:
for i,line in enumerate(f, start=1):
if start<=i<=end:
print(f"{i:4d}: {line.rstrip()}")
if i>end:
break
PY
echo "== tagExists usages in file =="
rg -n "tagExists\(" "$FILE"Repository: patternfly/patternfly-cli
Length of output: 1573
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="src/bump-prerelease.ts"
echo "== Snippet around tagExists usage (lines 110-150) =="
python3 - <<'PY'
path="src/bump-prerelease.ts"
start,end=105,153
with open(path,'r',encoding='utf-8') as f:
for i,line in enumerate(f, start=1):
if start<=i<=end:
print(f"{i:4d}: {line.rstrip()}")
if i>end:
break
PYRepository: patternfly/patternfly-cli
Length of output: 2074
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="src/bump-prerelease.ts"
python3 - <<'PY'
path="src/bump-prerelease.ts"
with open(path,'r',encoding='utf-8') as f:
for i,line in enumerate(f, start=1):
if i<=170:
print(f"{i:4d}: {line.rstrip()}")
PYRepository: patternfly/patternfly-cli
Length of output: 5757
Narrow tag existence check to tags only (refs/tags) — tagExists() currently uses git rev-parse <tag> (line 76), which can resolve non-tag refs and cause false “already exists” errors; verify refs/tags/${tag} instead.
Suggested fix
async function tagExists(tag: string, cwd: string): Promise<boolean> {
try {
- await execa('git', ['rev-parse', tag], { cwd });
+ await execa('git', ['rev-parse', '--verify', '--quiet', `refs/tags/${tag}`], { cwd });
return true;
} catch {
return false;
}
}🤖 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 `@src/bump-prerelease.ts` around lines 74 - 80, tagExists currently calls git
rev-parse on the plain tag which can resolve non-tag refs; change the execa call
in function tagExists to resolve the tag under refs/tags by calling git
rev-parse refs/tags/${tag} (still passing the cwd option and preserving the
existing try/catch and boolean return behavior) so the check only succeeds for
actual annotated/created tags.
What / why
Added new command that can bump to the next prerelease for a repo.
How to test
Go to a repo and run "pfcli bump-prerelease --dry-run" verify the next minor version would be bumped.
Go to a repo and run "pfcli bump-prerelease --dry-run --major" verify the next major version would be bumped.
Checklist
npm run lintandnpm testpass locallyfeat:,fix:,docs:,chore:Summary by CodeRabbit
New Features
bump-prereleaseCLI command to create and manage prerelease tags with support for--majorand--dry-runoptions.Documentation
bump-prereleasecommand.Tests
Chores