feat: auto-create profile README for new users on setup#3954
feat: auto-create profile README for new users on setup#3954marcusquinn merged 2 commits intomainfrom
Conversation
- Add 'init' command to profile-readme-helper.sh that creates the username/username GitHub repo, seeds a starter README with stat markers, and registers it in repos.json with priority: 'profile' - Wire init into setup.sh so it runs automatically during install/update when no profile repo exists and gh CLI is authenticated - Add footnote explaining why model savings are modest (cache reads dominate token volume, cache prices are similar across models) - Fix hardcoded marcusquinn/aidevops link in UPDATED timestamp to use generic aidevops.sh URL
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the user experience by automating the setup of GitHub profile READMEs. It introduces a new command to create, initialize, and register the profile repository, which is then seamlessly integrated into the main setup script. This automation streamlines the onboarding process for new users and ensures consistent configuration, while also providing clearer explanations for model cost savings and correcting a minor branding link. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, 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 have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughThis PR adds a new initialization workflow to the profile README helper that creates and seeds a GitHub profile repository when missing, requiring gh CLI authentication. It integrates the new Changes
Sequence Diagram(s)sequenceDiagram
participant User as User/CLI
participant Helper as profile-readme-helper.sh
participant GH as gh CLI
participant GitHub as GitHub API
participant FS as Local Filesystem
participant Config as repos.json
User->>Helper: cmd_init
Helper->>GH: Check gh authentication
GH-->>Helper: Auth status confirmed
Helper->>GH: Get authenticated user
GH-->>Helper: GitHub username
Helper->>GitHub: Create/verify profile repo
GitHub-->>Helper: Repo exists/created
Helper->>FS: Clone repo locally
FS-->>Helper: Repo cloned
Helper->>FS: Seed starter README with stat markers
FS-->>Helper: README seeded
Helper->>Config: Register repo in repos.json
Config-->>Helper: Registered
Helper->>Helper: Invoke cmd_update
Helper->>FS: Push initial README
FS-->>User: Init complete
sequenceDiagram
participant Setup as setup.sh
participant Config as repos.json
participant Helper as profile-readme-helper.sh
participant GH as gh CLI
participant Cron as Scheduler (cron/launchd)
Setup->>Config: Check repos.json for profile-priority
alt Profile repo found
Config-->>Setup: Profile repo exists
Setup->>Cron: Install daily update schedule
else Profile repo missing & gh available
Config-->>Setup: No profile repo found
Setup->>Helper: Execute init workflow
Helper->>GH: Authenticate & create repo
GH-->>Helper: Repo initialized
Setup->>Config: Profile repo now registered
Setup->>Cron: Install daily update schedule
else Profile repo missing & gh unavailable
Setup->>Setup: Skip scheduling
end
Cron->>Helper: Daily trigger at 06:00
Helper->>FS: Update profile README
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Multiple logic flows modified across two files with new initialization path, state management via repos.json, conditional scheduling logic, and multi-stage interaction with gh CLI and GitHub API requiring careful validation of authentication handling and edge cases. Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 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 |
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Mon Mar 9 03:47:08 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
setup.sh (1)
1278-1278: Redundant stderr redirection.
&>/dev/nullalready redirects both stdout and stderr. The trailing2>&1is redundant.🧹 Minor cleanup
- if [[ -x "$pr_script" ]] && command -v gh &>/dev/null && gh auth status &>/dev/null 2>&1; then + if [[ -x "$pr_script" ]] && command -v gh &>/dev/null && gh auth status &>/dev/null; then🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@setup.sh` at line 1278, The conditional in setup.sh uses redundant stderr redirection: in the if condition combining command -v gh &>/dev/null and gh auth status &>/dev/null 2>&1, remove the trailing 2>&1 so both checks consistently use &>/dev/null; update the condition referencing command -v gh and gh auth status (and the if test around "$pr_script") to use only &>/dev/null for redirection..agents/scripts/profile-readme-helper.sh (2)
725-747: Temporary file cleanup on jq failure.If the
jqcommand succeeds butmvfails (e.g., permission issues), the temp file remains orphaned. Consider adding a trap or explicit cleanup on failure.🛡️ Defensive cleanup pattern
if [[ "$already_registered" == "0" ]]; then echo "Registering profile repo in repos.json" local tmp_json tmp_json=$(mktemp) + # Ensure cleanup on failure + trap "rm -f '$tmp_json'" RETURN jq --arg path "$repo_dir" --arg slug "$repo_slug" ' .initialized_repos += [{ "path": $path, "slug": $slug, "priority": "profile", "pulse": false, "maintainer": ($slug | split("/")[0]) }] ' "$repos_json" >"$tmp_json" && mv "$tmp_json" "$repos_json" + trap - RETURNAlternatively, use a consistent pattern with explicit
rm -f "$tmp_json"in an else branch or after the conditional block.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.agents/scripts/profile-readme-helper.sh around lines 725 - 747, The temp-file created as tmp_json after running jq may be left behind if jq succeeds but mv fails; update the blocks around the jq -> mv sequence (the tmp_json variable usage) to ensure cleanup on failure by adding a trap or explicit fallback removal: after creating tmp_json and running jq, handle the case where mv fails by removing tmp_json (e.g., check the mv exit status and rm -f "$tmp_json" on failure) and/or install a trap that removes tmp_json on EXIT if it still exists; apply this to both the "registering" branch and the "Ensure priority" branch so orphaned temp files cannot remain.
652-657: Merge nested conditionals for clarity.Per static analysis, the nested
ifstatements can be merged into a single condition for improved readability.🧹 Merge if statements
- if [[ -n "$existing_profile" && "$existing_profile" != "null" ]]; then - if [[ -d "$existing_profile" ]]; then - echo "Profile repo already initialized at $existing_profile" - return 0 - fi - fi + if [[ -n "$existing_profile" && "$existing_profile" != "null" && -d "$existing_profile" ]]; then + echo "Profile repo already initialized at $existing_profile" + return 0 + fi🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.agents/scripts/profile-readme-helper.sh around lines 652 - 657, Merge the nested conditionals that check existing_profile by replacing the two if blocks that test [[ -n "$existing_profile" && "$existing_profile" != "null" ]] and then [[ -d "$existing_profile" ]] with a single combined conditional using && so the check becomes one if that tests non-empty/non-"null" and directory existence in the same expression; keep the same body (echo "Profile repo already initialized at $existing_profile" and return 0) and ensure you reference the same variable existing_profile and preserve current behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.agents/scripts/profile-readme-helper.sh:
- Line 663: The gh create command is using the wrong slug; change the call that
currently uses gh_user to use the repo_slug variable
(repo_slug="${gh_user}/${gh_user}") so it matches the earlier gh repo view
check, and add the --add-readme flag to initialize README.md (i.e., replace the
existing gh repo create invocation with one that uses repo_slug and includes
--add-readme, keeping --public and --description intact).
---
Nitpick comments:
In @.agents/scripts/profile-readme-helper.sh:
- Around line 725-747: The temp-file created as tmp_json after running jq may be
left behind if jq succeeds but mv fails; update the blocks around the jq -> mv
sequence (the tmp_json variable usage) to ensure cleanup on failure by adding a
trap or explicit fallback removal: after creating tmp_json and running jq,
handle the case where mv fails by removing tmp_json (e.g., check the mv exit
status and rm -f "$tmp_json" on failure) and/or install a trap that removes
tmp_json on EXIT if it still exists; apply this to both the "registering" branch
and the "Ensure priority" branch so orphaned temp files cannot remain.
- Around line 652-657: Merge the nested conditionals that check existing_profile
by replacing the two if blocks that test [[ -n "$existing_profile" &&
"$existing_profile" != "null" ]] and then [[ -d "$existing_profile" ]] with a
single combined conditional using && so the check becomes one if that tests
non-empty/non-"null" and directory existence in the same expression; keep the
same body (echo "Profile repo already initialized at $existing_profile" and
return 0) and ensure you reference the same variable existing_profile and
preserve current behavior.
In `@setup.sh`:
- Line 1278: The conditional in setup.sh uses redundant stderr redirection: in
the if condition combining command -v gh &>/dev/null and gh auth status
&>/dev/null 2>&1, remove the trailing 2>&1 so both checks consistently use
&>/dev/null; update the condition referencing command -v gh and gh auth status
(and the if test around "$pr_script") to use only &>/dev/null for redirection.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 04e90a41-e947-4b72-8d3b-a2146dd169b9
📒 Files selected for processing (2)
.agents/scripts/profile-readme-helper.shsetup.sh
There was a problem hiding this comment.
Code Review
This pull request introduces a valuable feature to automatically create and initialize a GitHub profile README for new users during setup. The implementation is solid, adding an init command to profile-readme-helper.sh and integrating it into setup.sh. My review focuses on improving error handling and script robustness by removing several instances of stderr suppression (2>/dev/null or &>/dev/null), which aligns with repository guidelines and enhances debuggability.
|
|
||
| # Get GitHub username | ||
| local gh_user | ||
| gh_user=$(gh api user --jq '.login' 2>/dev/null) || { |
There was a problem hiding this comment.
Suppressing stderr with 2>/dev/null for the gh api call hides potentially useful error messages. If the command fails for reasons other than authentication (e.g., network issues, API changes), the || block will execute, but you lose valuable debugging information from the gh CLI itself. It's better to let gh print its own errors to stderr.
| gh_user=$(gh api user --jq '.login' 2>/dev/null) || { | |
| gh_user=$(gh api user --jq '.login') || { |
References
- Avoid using '2>/dev/null' for blanket suppression of command errors in shell scripts to ensure that authentication, syntax, or system issues remain visible for debugging.
| existing_profile=$(jq -r ' | ||
| if .initialized_repos then | ||
| .initialized_repos[] | select(.priority == "profile") | .path | ||
| else | ||
| to_entries[] | select(.value.priority == "profile") | .value.path | ||
| end | ||
| ' "$repos_json" 2>/dev/null | head -1) |
There was a problem hiding this comment.
Suppressing stderr for jq with 2>/dev/null can hide important errors. If repos.json is malformed, jq will fail silently, and the script might proceed with incorrect assumptions. Removing 2>/dev/null will make parsing errors visible, which is crucial for debugging.
| existing_profile=$(jq -r ' | |
| if .initialized_repos then | |
| .initialized_repos[] | select(.priority == "profile") | .path | |
| else | |
| to_entries[] | select(.value.priority == "profile") | .value.path | |
| end | |
| ' "$repos_json" 2>/dev/null | head -1) | |
| existing_profile=$(jq -r ' | |
| if .initialized_repos then | |
| .initialized_repos[] | select(.priority == "profile") | .path | |
| else | |
| to_entries[] | select(.value.priority == "profile") | .value.path | |
| end | |
| ' "$repos_json" | head -1) |
References
- When reporting errors for failed file operations in shell scripts, such as 'jq' writes, include the file path in the error message. Avoid suppressing stderr with '2>/dev/null' to ensure that diagnostic information about malformed files or write failures is visible.
| # Clone if not already local | ||
| if [[ ! -d "$repo_dir" ]]; then | ||
| echo "Cloning $repo_slug to $repo_dir" | ||
| git clone "git@github.com:${repo_slug}.git" "$repo_dir" 2>/dev/null || |
There was a problem hiding this comment.
While the intention to silently fall back from SSH to HTTPS for git clone is clear, suppressing stderr with 2>/dev/null hides all errors. This includes potential configuration issues or other problems unrelated to SSH key availability, which could be valuable for debugging. It's better to allow error messages to be visible. For git clone, consider using the -q flag to suppress standard output while keeping stderr visible for debugging.
| git clone "git@github.com:${repo_slug}.git" "$repo_dir" 2>/dev/null || | |
| git clone -q "git@github.com:${repo_slug}.git" "$repo_dir" || |
References
- When using git commands (like 'init', 'remote') in shell scripts, use the '-q' flag to suppress standard output instead of '2>/dev/null', ensuring that error messages on stderr remain visible for debugging.
|
|
||
| # Get display name from git config or GitHub | ||
| local display_name | ||
| display_name=$(git config --global user.name 2>/dev/null || echo "$gh_user") |
There was a problem hiding this comment.
Suppressing stderr for git config with 2>/dev/null can hide underlying issues with the git configuration. If the command fails for a reason other than user.name not being set, the error message would be lost, making debugging harder. It's better to let potential errors be displayed.
| display_name=$(git config --global user.name 2>/dev/null || echo "$gh_user") | |
| display_name=$(git config --global user.name || echo "$gh_user") |
References
- Avoid using '2>/dev/null' for blanket suppression of command errors in shell scripts to ensure that authentication, syntax, or system issues remain visible for debugging.
| README | ||
|
|
||
| git -C "$repo_dir" add README.md | ||
| git -C "$repo_dir" commit -m "feat: initialize profile README with aidevops stat markers" --no-verify 2>/dev/null || true |
There was a problem hiding this comment.
Using 2>/dev/null with git commit suppresses potentially important error messages. For instance, if git is not configured with a user name/email, the commit will fail, but the reason will be hidden. The || true correctly prevents the script from exiting, but removing 2>/dev/null would improve debuggability by showing why the command failed.
| git -C "$repo_dir" commit -m "feat: initialize profile README with aidevops stat markers" --no-verify 2>/dev/null || true | |
| git -C "$repo_dir" commit -m "feat: initialize profile README with aidevops stat markers" --no-verify || true |
References
- In shell scripts with 'set -e' enabled, use '|| true' to prevent the script from exiting when a command like 'jq' fails on an optional lookup. Do not suppress stderr with '2>/dev/null' so that actual syntax or system errors remain visible for debugging.
|
|
||
| git -C "$repo_dir" add README.md | ||
| git -C "$repo_dir" commit -m "feat: initialize profile README with aidevops stat markers" --no-verify 2>/dev/null || true | ||
| git -C "$repo_dir" push origin main 2>/dev/null || git -C "$repo_dir" push origin master 2>/dev/null || { |
There was a problem hiding this comment.
Suppressing stderr for git push with 2>/dev/null hides the reason for push failures. If both pushes to main and master fail, the user only gets a generic 'failed to push' warning without knowing why (e.g., authentication failure, network error, non-fast-forward updates). Removing 2>/dev/null will provide the actual error message from git, which is crucial for debugging.
| git -C "$repo_dir" push origin main 2>/dev/null || git -C "$repo_dir" push origin master 2>/dev/null || { | |
| git -C "$repo_dir" push origin main || git -C "$repo_dir" push origin master || { |
References
- Avoid using '2>/dev/null' for blanket suppression of command errors in shell scripts to ensure that authentication, syntax, or system issues remain visible for debugging.
| already_registered=$(jq -r --arg path "$repo_dir" ' | ||
| if .initialized_repos then | ||
| [.initialized_repos[] | select(.path == $path)] | length | ||
| else | ||
| [to_entries[] | select(.value.path == $path)] | length | ||
| end | ||
| ' "$repos_json" 2>/dev/null) |
There was a problem hiding this comment.
Suppressing stderr for jq with 2>/dev/null can hide important errors. If repos.json is malformed, jq will fail silently, and the script might proceed with incorrect assumptions. Removing 2>/dev/null will make parsing errors visible, aiding in debugging.
| already_registered=$(jq -r --arg path "$repo_dir" ' | |
| if .initialized_repos then | |
| [.initialized_repos[] | select(.path == $path)] | length | |
| else | |
| [to_entries[] | select(.value.path == $path)] | length | |
| end | |
| ' "$repos_json" 2>/dev/null) | |
| already_registered=$(jq -r --arg path "$repo_dir" ' | |
| if .initialized_repos then | |
| [.initialized_repos[] | select(.path == $path)] | length | |
| else | |
| [to_entries[] | select(.value.path == $path)] | length | |
| end | |
| ' "$repos_json") |
References
- When reporting errors for failed file operations in shell scripts, such as 'jq' writes, include the file path in the error message. Avoid suppressing stderr with '2>/dev/null' to ensure that diagnostic information about malformed files or write failures is visible.
… redirect Addresses CodeRabbit review: use consistent repo_slug variable in gh repo create to match gh repo view check, add --add-readme flag to initialize README.md on creation, remove redundant 2>&1 after &>.
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Mon Mar 9 03:55:26 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
|



Summary
profile-readme-helper.sh initcommand that auto-creates theusername/usernameGitHub profile repo, seeds a starter README with stat markers (<!-- STATS-START/END -->), registers it inrepos.jsonwithpriority: "profile", and runs the first stats updateinitintosetup.shso it runs automatically during install/update when no profile repo exists andghCLI is authenticatedmarcusquinn/aidevopslink in UPDATED timestamp to use genericaidevops.shURLUser experience
On
aidevops updateor fresh install:ghis authenticated and no profile repo exists → auto-creates itIdempotent — re-running
initwhen already set up prints "already initialized" and exits.Files changed
.agents/scripts/profile-readme-helper.sh— newcmd_init, footnote, URL fixsetup.sh— auto-init before scheduled job setupSummary by CodeRabbit
Release Notes