Skip to content

feat: add automated upgrade workflow for overlays - #619

Merged
shunkakinoki merged 12 commits into
mainfrom
feat-make-upgrade
Jan 19, 2026
Merged

feat: add automated upgrade workflow for overlays#619
shunkakinoki merged 12 commits into
mainfrom
feat-make-upgrade

Conversation

@shunkakinoki

@shunkakinoki shunkakinoki commented Jan 19, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add automated GitHub Action workflow for overlay upgrades
  • Schedule daily runs at 2 AM UTC with manual dispatch option
  • Implement upgrade-overlays.sh script for all overlay updates
  • Create pull request automatically with upgrade changes
  • Add upgrade-check job to ensure workflow success

Changes

  • New .github/workflows/upgrade.yml workflow file
  • Automated overlay upgrade process with proper error handling
  • Integration with existing upgrade infrastructure
  • Maintains branch hygiene with automatic cleanup

Testing

  • Workflow validated with proper GitHub Actions syntax
  • Concurrency controls prevent duplicate runs
  • Proper token handling for pull request creation

Summary by cubic

Automates Nix overlay upgrades with a nightly GitHub Action and a tested, extensible upgrade script that opens PRs with changes. This reduces manual upkeep and keeps overlays current.

  • New Features

    • Scheduled workflow (.github/workflows/upgrade.yml) runs daily at 02:00 UTC, supports manual dispatch, enforces concurrency, and creates PRs via PAT_TOKEN.
    • Extensible upgrade script (scripts/upgrade-overlays.sh) with robust error handling; upgrades one overlay or all.
    • Makefile targets: upgrade, upgrade-overlays, upgrade-clawdbot.
    • New shpec tests for the script and coverage wiring.
  • Refactors

    • Flake modules now inherit env/host from inputs; pass inputs to Home Manager and nix-darwin; general cleanup.
    • Clawdbot module cleans stale port-guard entries and maintains the SSH tunnel on macOS remote mode.
    • Cargo globals installer skips already-installed versions; fish helpers bump Codex model to gpt-5.2-codex.
    • Config/deps: add claude-mem plugin, enable aider-chat and qwen-code, add mistral-vibe; update Cargo/uv/flake locks.

Written for commit 9e983f5. Summary will update on new commits.

Copilot AI review requested due to automatic review settings January 19, 2026 21:39
@mesa-dot-dev

mesa-dot-dev Bot commented Jan 19, 2026

Copy link
Copy Markdown

You do not have enough credits to review this pull request. Please purchase more credits to continue.

@coderabbitai

coderabbitai Bot commented Jan 19, 2026

Copy link
Copy Markdown
📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Automated overlay upgrade workflow with GitHub Actions integration
    • New SSH tunnel support for macOS remote deployments
    • Added claude-mem plugin to editor configuration
  • Improvements

    • Enhanced package management with platform-specific installations for Linux
    • Enabled additional development tools (aider-chat, qwen-code)
    • Optimized cargo installation to skip already-installed packages
    • Updated Codex model version for improved code generation
    • Improved shell linting with virtual environment exclusions
    • Refactored infrastructure configuration for better modularity
  • Tests

    • Comprehensive test coverage for automated upgrade functionality

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Introduces automated overlay upgrade infrastructure via GitHub Actions workflow and supporting Bash script, refactors flake.nix to use modular inputsWithLib binding, enhances home-manager modules with inputs parameter support, adds new dependencies and Claude plugins, updates Codex model versions, and includes comprehensive test coverage.

Changes

Cohort / File(s) Summary
GitHub Actions & Automation
​.github/workflows/upgrade.yml, scripts/upgrade-overlays.sh, spec/upgrade_overlays_spec.sh, spec/coverage_spec.sh
New scheduled GitHub Actions workflow triggers overlay upgrades via upgrade-overlays.sh script; script automates clawdbot release detection, hash computation, and overlay file updates; comprehensive test suite validates upgrade logic, dependency checks, and edge cases; coverage mappings extended to include new script.
Flake & NixOS Restructuring
flake.nix, nix-darwin/default.nix, hosts/nixos/default.nix
Major flake.nix refactor introduces inputsWithLib binding augmenting inputs with env and host modules; perSystem block restructured for devenv/treefmt configuration; darwin configurations now use mkDarwin function; nix-darwin and nixos modules updated to accept and utilize inputs parameter; home-manager receives inputs via extraSpecialArgs.
Home-Manager Module Enhancements
home-manager/modules/clawdbot/default.nix, home-manager/modules/cargo-globals/install-cargo-globals.sh, home-manager/packages/default.nix
clawdbot module now accepts inputs parameter, adds home.activation.clawdbotCleanPortGuard cleanup on macOS, and introduces launchd.agents.clawdbot-tunnel for SSH tunneling; cargo-globals script implements per-package installed-check to skip already-installed crates; packages module updates isCI binding to use inputs.env.isCI and conditionally enables aider-chat and qwen-code with platform-specific extras.
Fish Shell & Model Updates
home-manager/programs/fish/functions/_coxe_function.fish, home-manager/programs/fish/functions/_coxeh_function.fish
Codex model specification updated from gpt-5-codex to gpt-5.2-codex in both function implementations.
Build Configuration
Makefile, Cargo.toml, pyproject.toml, lib.rs
Makefile adds upgrade, upgrade-overlays, upgrade-clawdbot targets; renames neovim-update to neovim-upgrade; adds shell-lint alias and extends shell-check exclusions; Cargo.toml defines library entry point; pyproject.toml adds mistral-vibe>=1.3.5 dependency; lib.rs created as empty placeholder.
Claude Configuration
config/claude/settings.json
Adds claude-mem plugin to enabledPlugins and introduces corresponding extraKnownMarketplaces entry with GitHub repository reference.
Submodule
dotagents
Submodule reference updated to latest commit.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant GA as GitHub Actions
    participant Script as upgrade-overlays.sh
    participant Nix as Nix/Hash Tools
    participant Git as Git/File System
    participant PR as Create PR Action

    User->>GA: Trigger (scheduled/manual)
    GA->>GA: Checkout + Install Nix
    GA->>Script: Execute with 'all' argument
    Script->>Nix: Fetch latest clawdbot release
    Script->>Nix: Get commit SHA for tag
    Script->>Nix: Compute source hash (nix-prefetch-url)
    Script->>Nix: Compute app bundle hash
    Script->>Git: Update overlays/default.nix<br/>(rev, hashes, version)
    Script->>GA: Return status
    GA->>PR: Create pull request<br/>(branch: chore/upgrade-overlays)
    PR->>GA: PR created
    GA->>GA: Run upgrade-check<br/>(alls-green verification)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Poem

🐰 Overlays upgrade with a hop and a whisk,
Automation flows—no manual risk!
Nix modules dance with inputs so spry,
Hash computations beneath the CI sky,
Pull requests bloom, and the tests all pass by! 🌱✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately summarizes the main change: introducing an automated upgrade workflow for overlays, which is the primary objective.
Description check ✅ Passed The PR description is detailed and comprehensive, covering the workflow automation, new scripts, testing, and related refactors that align with the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat-make-upgrade

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @shunkakinoki, 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 maintainability and automation of the repository by introducing an automated workflow for updating Nix overlays. It centralizes the upgrade logic into a new script, updates various core dependencies, and includes specific fixes and improvements for managing Rust global packages and the Clawdbot application. These changes aim to streamline development operations and ensure the environment remains current and stable with minimal manual intervention.

Highlights

  • Automated Overlay Upgrade Workflow: Introduced a new GitHub Actions workflow (.github/workflows/upgrade.yml) to automate the process of upgrading Nix overlays. This workflow is scheduled to run daily at 2 AM UTC and can also be triggered manually.
  • New Overlay Upgrade Script: A new shell script (scripts/upgrade-overlays.sh) has been added to handle the logic for updating specific overlays. It currently supports upgrading the clawdbot overlay by fetching the latest release, computing source hashes, and updating the overlays/default.nix file.
  • Nix Flake and Dependency Updates: The flake.lock file has been updated, reflecting new revisions and hashes for several Nix flake inputs, including devenv, home-manager, neovim-nightly-overlay, nix-clawdbot, and nixpkgs. This ensures all dependencies are up-to-date.
  • Improved Cargo Global Package Management: The install-cargo-globals.sh script now intelligently checks if a Rust global package is already installed at the required version before attempting to reinstall it, optimizing the installation process.
  • Clawdbot Integration and Fixes: The clawdbot overlay has been updated to its latest version. Additionally, specific workarounds for macOS have been implemented, including cleaning stale port-guard.json entries and establishing a persistent SSH tunnel via launchd for the kyber gateway, addressing known issues with the Clawdbot.app.
  • Updated Codex Model: The codex model used in fish shell functions (_coxe_function.fish and _coxeh_function.fish) has been updated from gpt-5-codex to gpt-5.2-codex.
Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/upgrade.yml
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@mesa-dot-dev

mesa-dot-dev Bot commented Jan 19, 2026

Copy link
Copy Markdown

Mesa Description

TL;DR

Added an automated GitHub Action workflow to upgrade overlays daily and create pull requests for the changes.

What changed?

  • New .github/workflows/upgrade.yml workflow file
  • Automated overlay upgrade process with daily scheduling and manual dispatch
  • Implementation of upgrade-overlays.sh script
  • Automatic pull request creation for upgrade changes
  • Addition of an upgrade-check job to ensure workflow success
  • Automated overlay upgrade process with proper error handling
  • Integration with existing upgrade infrastructure
  • Maintains branch hygiene with automatic cleanup

Description generated by Mesa. Update settings

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 introduces an automated workflow for upgrading overlays in the Nix configuration, with a focus on the clawdbot overlay. The automation runs daily via GitHub Actions and can be manually triggered.

Changes:

  • Add GitHub Actions workflow for automated overlay upgrades with daily scheduling
  • Implement upgrade-overlays.sh script with comprehensive test coverage
  • Introduce Makefile targets for upgrade operations
  • Refactor flake.nix to inject env/host as inputs for consistent access across modules

Reviewed changes

Copilot reviewed 18 out of 21 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
.github/workflows/upgrade.yml GitHub Actions workflow for scheduled overlay upgrades with PR creation
scripts/upgrade-overlays.sh Shell script implementing overlay upgrade logic with GitHub API integration
spec/upgrade_overlays_spec.sh Comprehensive test suite for the upgrade script
spec/coverage_spec.sh Updated test coverage tracking to include new script
Makefile New upgrade targets and aliases for managing overlays
flake.nix Refactored to expose env/host libraries as inputs
home-manager/modules/clawdbot/default.nix Added SSH tunnel and port-guard cleanup for clawdbot
home-manager/modules/cargo-globals/install-cargo-globals.sh Optimized to skip already-installed packages
pyproject.toml Added mistral-vibe dependency
Cargo.toml Added lib path configuration
lib.rs Empty Rust library file
config/claude/settings.json Added claude-mem plugin
home-manager/programs/fish/functions/*.fish Updated codex model version
dotagents Updated submodule reference

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

Comment thread lib.rs
@@ -0,0 +1 @@

Copilot AI Jan 19, 2026

Copy link

Choose a reason for hiding this comment

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

This file contains only whitespace. Consider either removing it if it's not needed, or adding a placeholder comment explaining its purpose if it's intentionally empty for future use.

Suggested change
// This library crate is intentionally left empty for now and reserved for future shared code.

Copilot uses AI. Check for mistakes.
@shunkakinoki
shunkakinoki enabled auto-merge (squash) January 19, 2026 21:41

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces an automated upgrade workflow for overlays, centered around a new upgrade-overlays.sh script, which is a great addition for maintainability. The PR also includes several related improvements, such as refactoring the Nix flake configuration, improving other scripts, and updating dependencies. The new upgrade script is well-structured, but there are opportunities to improve its robustness and efficiency. Specifically, reducing API calls and using more resilient methods for file updates would make it even better. The accompanying tests for the new script could also be strengthened by testing the script's functions directly rather than a simplified copy of the logic. Overall, this is a valuable feature addition with a few areas for refinement.

Comment on lines +53 to +54
ref_type=$(gh api "repos/$owner/$repo/git/refs/tags/$tag" --jq '.object.type' 2>/dev/null || echo "")
ref_sha=$(gh api "repos/$owner/$repo/git/refs/tags/$tag" --jq '.object.sha' 2>/dev/null || echo "")

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.

medium

To improve efficiency, you can combine these two gh api calls into a single one. This reduces the number of network requests and makes the script slightly faster and more atomic.

Suggested change
ref_type=$(gh api "repos/$owner/$repo/git/refs/tags/$tag" --jq '.object.type' 2>/dev/null || echo "")
ref_sha=$(gh api "repos/$owner/$repo/git/refs/tags/$tag" --jq '.object.sha' 2>/dev/null || echo "")
response=$(gh api "repos/$owner/$repo/git/refs/tags/$tag" 2>/dev/null || echo "")
ref_type=$(echo "$response" | jq -r '.object.type // ""')
ref_sha=$(echo "$response" | jq -r '.object.sha // ""')

Comment on lines +133 to +134
sed_inplace "s|rev = \"[^\"]*\";|rev = \"$rev\";|" "$OVERLAY_FILE"
sed_inplace "s|hash = \"sha256-[^\"]*\";|hash = \"$source_sri\";|" "$OVERLAY_FILE"

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.

medium

These sed commands are a bit fragile as they rely on replacing the first match for rev and hash in the file. To make this more robust and ensure you're only modifying the clawdbotSourceOverride block, you can use sed with an address range. This will scope the replacements to the correct block, preventing accidental changes elsewhere in the file.

Suggested change
sed_inplace "s|rev = \"[^\"]*\";|rev = \"$rev\";|" "$OVERLAY_FILE"
sed_inplace "s|hash = \"sha256-[^\"]*\";|hash = \"$source_sri\";|" "$OVERLAY_FILE"
sed_inplace "/clawdbotSourceOverride = {/,/};/ { s|rev = \"[^\"]*\";|rev = \"$rev\";|; s|hash = \"sha256-[^\"]*\";|hash = \"$source_sri\";|; }" "$OVERLAY_FILE"

Comment on lines +142 to +149
awk -v new_hash="$app_sri" '
/clawdbotAppOverride = \{/ { in_app_override = 1 }
in_app_override && /hash = "sha256-/ {
sub(/hash = "sha256-[^"]*"/, "hash = \"" new_hash "\"")
in_app_override = 0
}
{ print }
' "$OVERLAY_FILE" >"$OVERLAY_FILE.tmp" && mv "$OVERLAY_FILE.tmp" "$OVERLAY_FILE"

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.

medium

This awk block for updating the app hash is clever, but it can be simplified and made more consistent with other updates by using sed with an address range. This approach is more concise and just as robust for this task.

Suggested change
awk -v new_hash="$app_sri" '
/clawdbotAppOverride = \{/ { in_app_override = 1 }
in_app_override && /hash = "sha256-/ {
sub(/hash = "sha256-[^"]*"/, "hash = \"" new_hash "\"")
in_app_override = 0
}
{ print }
' "$OVERLAY_FILE" >"$OVERLAY_FILE.tmp" && mv "$OVERLAY_FILE.tmp" "$OVERLAY_FILE"
sed_inplace "/clawdbotAppOverride = {/,/};/ s|hash = \"sha256-[^\"]*\"|hash = \"$app_sri\"|" "$OVERLAY_FILE"

Comment on lines +93 to +191
Describe 'clawdbot upgrade'
setup() {
mock_bin_setup gh nix-prefetch-url nix jq
TEMP_DIR=$(mktemp -d)
OVERLAY_FILE="$TEMP_DIR/overlays/default.nix"
mkdir -p "$TEMP_DIR/overlays"

# Create a minimal overlay file with the expected structure
cat >"$OVERLAY_FILE" <<'NIX'
{ inputs }:
let
# Override clawdbot source to v2026.1.15
clawdbotSourceOverride = {
owner = "clawdbot";
repo = "clawdbot";
rev = "abc123";
hash = "sha256-OLDHASH1234567890=";
pnpmDepsHash = "sha256-PNPMHASH1234567890=";
};
# Override clawdbot-app to v2026.1.15 (fixes broken app package)
clawdbotAppOverride = {
version = "2026.1.15";
url = "https://github.com/clawdbot/clawdbot/releases/download/v2026.1.15/Clawdbot-2026.1.15.zip";
hash = "sha256-OLDAPPHASH1234567890=";
};
in
[
(
final: prev:
let
clawdbotVersion = "2026.1.15";
in
{}
)
]
NIX

# Create a test script that uses our temp overlay file
TEMP_SCRIPT="$TEMP_DIR/upgrade-test.sh"
cat >"$TEMP_SCRIPT" <<SCRIPT
#!/usr/bin/env bash
set -euo pipefail

OVERLAY_FILE="$OVERLAY_FILE"

# Mock implementations that return test values
fetch_latest_release() {
echo "v2026.1.16"
}

get_tag_commit() {
echo "newcommit456"
}

compute_source_hash() {
echo "0123456789abcdef"
}

convert_to_sri() {
echo "sha256-NEWHASH="
}

sed_inplace() {
if [[ "\$OSTYPE" == "darwin"* ]]; then
sed -i '' "\$@"
else
sed -i "\$@"
fi
}

upgrade_clawdbot() {
local current_version tag version rev

current_version=\$(grep -oE 'clawdbotVersion = "[^"]+"' "\$OVERLAY_FILE" | head -1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+(-[0-9]+)?' || echo "unknown")
echo "Current version: \$current_version"

tag=\$(fetch_latest_release)
version="\${tag#v}"
echo "Latest version: \$version"

if [ "\$current_version" = "\$version" ]; then
echo "Already on latest version (\$version)"
return 0
fi

rev=\$(get_tag_commit)
echo "Commit: \$rev"

echo "Updating overlay file..."
sed_inplace "s|rev = \"[^\"]*\";|rev = \"\$rev\";|" "\$OVERLAY_FILE"
sed_inplace "s|clawdbotVersion = \"[^\"]*\";|clawdbotVersion = \"\$version\";|" "\$OVERLAY_FILE"

echo "clawdbot upgraded from \$current_version to \$version"
}

upgrade_clawdbot
SCRIPT
chmod +x "$TEMP_SCRIPT"
}

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.

medium

The testing strategy here is a bit brittle. By creating a temporary script with a simplified copy of the upgrade_clawdbot function, you're not testing the actual implementation from scripts/upgrade-overlays.sh. If the main script's logic changes, these tests won't catch regressions unless the test script is also manually updated.

A more robust approach is to source the script under test and then mock the external commands or functions (like fetch_latest_release, get_tag_commit, etc.) directly in your test setup. This allows you to test the real implementation of upgrade_clawdbot.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@Cargo.toml`:
- Around line 6-8: The [package] table keys in Cargo.toml are out of the
project's alphabetical order guideline; edit the Cargo.toml [package] section
and reorder the keys so they appear as edition, name, version (alphabetically),
leaving values unchanged; ensure the [lib] path = "lib.rs" remains intact and no
other sections or formatting are modified.

In `@Makefile`:
- Around line 162-163: The update Makefile target currently depends on a
non-existent target named neovim-update; change the dependency in the update
target declaration from neovim-update to the correct target name neovim-upgrade
so it matches the actual target definition and the upgrade target dependency.

In `@scripts/upgrade-overlays.sh`:
- Around line 129-156: The sed_inplace replacement for hash = "sha256-..." is
too broad and will overwrite multiple hashes in the overlay (including
pnpmDepsHash and the app hash); narrow the change to only the clawdbot source
block by matching context around clawdbotSourceOverride (e.g., detect the
"clawdbotSourceOverride = {" block) or use an awk/grep-based block-aware update
similar to the existing clawdbotAppOverride handling, and update the code that
calls sed_inplace and the awk block to target only the intended hash in
OVERLAY_FILE while leaving pnpmDepsHash and the app hash untouched; update
references to clawdbotSourceOverride, pnpmDepsHash, clawdbotAppOverride,
sed_inplace and the existing awk logic to implement this block-specific
replacement.

In `@spec/upgrade_overlays_spec.sh`:
- Around line 220-230: The two examples "It 'updates rev in overlay file'" and
"It 'updates clawdbotVersion in overlay file'" both run bash "$TEMP_SCRIPT" and
assert on "$OVERLAY_FILE", causing test state to leak between them; fix by
either moving each It block into its own Describe (or Context) with independent
setup/cleanup so "$TEMP_SCRIPT" is executed and "$OVERLAY_FILE" is reset for
each test, or combine both assertions into a single It that runs bash
"$TEMP_SCRIPT" once and checks for both 'rev = "newcommit456"' and
'clawdbotVersion = "2026.1.16"' against "$OVERLAY_FILE".
🧹 Nitpick comments (5)
scripts/upgrade-overlays.sh (2)

31-42: Dependency check may fail on empty array with set -u.

In older Bash versions (< 4.4), accessing ${#missing[@]} on an uninitialized or empty array under set -u can cause an "unbound variable" error. Initialize the array explicitly or use ${missing[@]+"${missing[@]}"} pattern for safer access.

♻️ Safer empty array check
 check_dependencies() {
-  local missing=()
+  local -a missing
+  missing=()
   for cmd in gh nix-prefetch-url nix jq; do
     if ! command -v "$cmd" &>/dev/null; then
       missing+=("$cmd")
     fi
   done
-  if [ ${`#missing`[@]} -ne 0 ]; then
+  if [ "${`#missing`[@]}" -gt 0 ]; then
     log_error "Missing required dependencies: ${missing[*]}"
     exit 1
   fi
 }

142-149: Potential silent failure on awk error.

If awk fails, the mv command will still execute (due to &&), but an empty or corrupted temp file could replace the original. Consider adding error handling.

♻️ Add error handling for awk/mv
-  awk -v new_hash="$app_sri" '
+  if ! awk -v new_hash="$app_sri" '
         /clawdbotAppOverride = \{/ { in_app_override = 1 }
         in_app_override && /hash = "sha256-/ {
             sub(/hash = "sha256-[^"]*"/, "hash = \"" new_hash "\"")
             in_app_override = 0
         }
         { print }
-    ' "$OVERLAY_FILE" >"$OVERLAY_FILE.tmp" && mv "$OVERLAY_FILE.tmp" "$OVERLAY_FILE"
+    ' "$OVERLAY_FILE" >"$OVERLAY_FILE.tmp"; then
+    log_error "Failed to update clawdbotAppOverride hash"
+    rm -f "$OVERLAY_FILE.tmp"
+    exit 1
+  fi
+  mv "$OVERLAY_FILE.tmp" "$OVERLAY_FILE"
.github/workflows/upgrade.yml (2)

17-22: Consider adding Nix store caching to improve workflow performance.

The workflow installs Nix but doesn't cache the Nix store. This will cause slower runs as dependencies are re-downloaded each time.

💡 Suggested improvement
      - name: Install Nix
        uses: cachix/install-nix-action@v31
        with:
          github_access_token: ${{ secrets.GITHUB_TOKEN }}
+     - name: Cache Nix store
+       uses: actions/cache@v4
+       with:
+         path: /nix
+         key: nix-${{ runner.os }}-${{ hashFiles('flake.lock') }}
+         restore-keys: |
+           nix-${{ runner.os }}-

Based on coding guidelines, caching Nix store and build artifacts improves performance.


43-46: Consider pinning alls-green to a specific version instead of release/v1.

Using @release/v1 references a branch that can change. For reproducibility and security, pin to a specific version tag or commit SHA.

💡 Suggested fix
      - name: Alls Green
-       uses: re-actors/alls-green@release/v1
+       uses: re-actors/alls-green@v1.2.2
        with:
          jobs: ${{ toJSON(needs) }}

Based on coding guidelines: use specific action versions (not @main or @master).

flake.nix (1)

83-151: Note that system = "aarch64-darwin" is hardcoded in multiple places, not just flake.nix.

Line 90 in flake.nix hardcodes the system, but ./hosts/darwin/default.nix (line 13) and ./named-hosts/galactica/default.nix (line 10) also hardcode it. The Makefile shows x86_64-darwin support is anticipated; parameterizing system across all darwin module imports would be prudent. Update hosts/darwin/default.nix to accept system as a parameter, pass it through from flake.nix, and do the same for named-hosts/galactica.

Comment thread Cargo.toml
Comment on lines +6 to +8
[lib]
path = "lib.rs"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Check if lib.rs exists at repository root and examine Cargo.toml
echo "=== Checking for lib.rs at repository root ==="
if [ -f "lib.rs" ]; then
  echo "✅ lib.rs found at repository root"
  wc -l lib.rs
else
  echo "❌ lib.rs NOT found at repository root"
fi

echo ""
echo "=== Examining full Cargo.toml ==="
cat -n Cargo.toml

echo ""
echo "=== Checking for src/lib.rs ==="
if [ -f "src/lib.rs" ]; then
  echo "✅ src/lib.rs exists (standard location)"
else
  echo "❌ src/lib.rs does NOT exist"
fi

echo ""
echo "=== Checking repository structure ==="
ls -la | head -20

Repository: shunkakinoki/dotfiles

Length of output: 1664


Reorder keys alphabetically in the [package] section.

The lib.rs file exists at the repository root and is properly configured. However, the keys in the [package] section should follow the coding guideline to sort keys alphabetically. Reorder as: edition, name, version.

🤖 Prompt for AI Agents
In `@Cargo.toml` around lines 6 - 8, The [package] table keys in Cargo.toml are
out of the project's alphabetical order guideline; edit the Cargo.toml [package]
section and reorder the keys so they appear as edition, name, version
(alphabetically), leaving values unchanged; ensure the [lib] path = "lib.rs"
remains intact and no other sections or formatting are modified.

Comment thread Makefile
Comment on lines 162 to 163
.PHONY: update
update: nix-update shell-update neovim-update ## Update Nix flake and configurations.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

grep -n 'neovim-update\|neovim-upgrade' Makefile

Repository: shunkakinoki/dotfiles

Length of output: 377


🏁 Script executed:

grep -n '\.PHONY: neovim-update\|^neovim-update:' Makefile

Repository: shunkakinoki/dotfiles

Length of output: 47


Fix target name on line 163: neovim-update should be neovim-upgrade.

The update target references neovim-update, but this target does not exist. The actual target is neovim-upgrade (defined on lines 537-538). Change line 163 to use neovim-upgrade as a dependency, matching the upgrade target on line 168 and the actual target definition.

🤖 Prompt for AI Agents
In `@Makefile` around lines 162 - 163, The update Makefile target currently
depends on a non-existent target named neovim-update; change the dependency in
the update target declaration from neovim-update to the correct target name
neovim-upgrade so it matches the actual target definition and the upgrade target
dependency.

Comment on lines +129 to +156
# Update overlay file
echo " Updating overlays/default.nix..."

# Update clawdbotSourceOverride
sed_inplace "s|rev = \"[^\"]*\";|rev = \"$rev\";|" "$OVERLAY_FILE"
sed_inplace "s|hash = \"sha256-[^\"]*\";|hash = \"$source_sri\";|" "$OVERLAY_FILE"

# Update clawdbotAppOverride
sed_inplace "s|version = \"[0-9][^\"]*\";|version = \"$version\";|" "$OVERLAY_FILE"
sed_inplace "s|url = \"https://github.com/clawdbot/clawdbot/releases/download/[^\"]*\";|url = \"$app_url\";|" "$OVERLAY_FILE"

# Update app hash (second hash in the file, after url)
# Use awk to update only the hash in clawdbotAppOverride block
awk -v new_hash="$app_sri" '
/clawdbotAppOverride = \{/ { in_app_override = 1 }
in_app_override && /hash = "sha256-/ {
sub(/hash = "sha256-[^"]*"/, "hash = \"" new_hash "\"")
in_app_override = 0
}
{ print }
' "$OVERLAY_FILE" >"$OVERLAY_FILE.tmp" && mv "$OVERLAY_FILE.tmp" "$OVERLAY_FILE"

# Update clawdbotVersion
sed_inplace "s|clawdbotVersion = \"[^\"]*\";|clawdbotVersion = \"$version\";|" "$OVERLAY_FILE"

# Update comment
sed_inplace "s|# Override clawdbot source to v[^ ]*|# Override clawdbot source to v$version|" "$OVERLAY_FILE"
sed_inplace "s|# Override clawdbot-app to v[^ ]* |# Override clawdbot-app to v$version |" "$OVERLAY_FILE"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

git ls-files | head -20

Repository: shunkakinoki/dotfiles

Length of output: 563


🏁 Script executed:

fd "upgrade-overlays" -o "default.nix"

Repository: shunkakinoki/dotfiles

Length of output: 206


🏁 Script executed:

git ls-files scripts/ overlays/

Repository: shunkakinoki/dotfiles

Length of output: 140


🏁 Script executed:

cat -n scripts/upgrade-overlays.sh | head -180

Repository: shunkakinoki/dotfiles

Length of output: 6651


🏁 Script executed:

cat -n overlays/default.nix

Repository: shunkakinoki/dotfiles

Length of output: 6309


🏁 Script executed:

cat -n overlays/default.nix | grep -E 'hash = "sha256-|version = "'

Repository: shunkakinoki/dotfiles

Length of output: 246


🏁 Script executed:

cat -n scripts/upgrade-overlays.sh | sed -n '129,156p'

Repository: shunkakinoki/dotfiles

Length of output: 1601


Apply context-aware patterns to all sed replacements to prevent unintended updates.

Line 134's pattern hash = "sha256-[^"]*" matches three separate hash values in the file: the source hash (line 8, intended), the pnpmDepsHash (line 9, unintended—this requires manual update per the warning on line 159), and the app hash (line 15, unintended—updated separately via awk on lines 142-149). A single sed invocation will replace all three, corrupting the file.

Use context-aware patterns for all replacements:

  • Wrap sed calls with block-specific markers or patterns (e.g., search for clawdbotSourceOverride = { before matching hash)
  • Alternatively, extend the awk approach used for the app hash to the source hash as well

This ensures only the intended lines are modified and pnpmDepsHash is never accidentally overwritten.

🤖 Prompt for AI Agents
In `@scripts/upgrade-overlays.sh` around lines 129 - 156, The sed_inplace
replacement for hash = "sha256-..." is too broad and will overwrite multiple
hashes in the overlay (including pnpmDepsHash and the app hash); narrow the
change to only the clawdbot source block by matching context around
clawdbotSourceOverride (e.g., detect the "clawdbotSourceOverride = {" block) or
use an awk/grep-based block-aware update similar to the existing
clawdbotAppOverride handling, and update the code that calls sed_inplace and the
awk block to target only the intended hash in OVERLAY_FILE while leaving
pnpmDepsHash and the app hash untouched; update references to
clawdbotSourceOverride, pnpmDepsHash, clawdbotAppOverride, sed_inplace and the
existing awk logic to implement this block-specific replacement.

Comment on lines +220 to +230
It 'updates rev in overlay file'
bash "$TEMP_SCRIPT" >/dev/null 2>&1
When run cat "$OVERLAY_FILE"
The output should include 'rev = "newcommit456"'
End

It 'updates clawdbotVersion in overlay file'
bash "$TEMP_SCRIPT" >/dev/null 2>&1
When run cat "$OVERLAY_FILE"
The output should include 'clawdbotVersion = "2026.1.16"'
End

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Test isolation concern: file state carries over between tests.

Tests "updates rev in overlay file" (Line 221) and "updates clawdbotVersion in overlay file" (Line 227) both run bash "$TEMP_SCRIPT" and then check the file state. Since ShellSpec runs tests sequentially within a Describe block sharing the same setup/cleanup, the second test relies on file state from the first test's execution.

Consider either:

  1. Using separate Describe blocks with independent setup for each file-state test, or
  2. Combining these into a single test that verifies both fields after one script run.
🤖 Prompt for AI Agents
In `@spec/upgrade_overlays_spec.sh` around lines 220 - 230, The two examples "It
'updates rev in overlay file'" and "It 'updates clawdbotVersion in overlay
file'" both run bash "$TEMP_SCRIPT" and assert on "$OVERLAY_FILE", causing test
state to leak between them; fix by either moving each It block into its own
Describe (or Context) with independent setup/cleanup so "$TEMP_SCRIPT" is
executed and "$OVERLAY_FILE" is reset for each test, or combine both assertions
into a single It that runs bash "$TEMP_SCRIPT" once and checks for both 'rev =
"newcommit456"' and 'clawdbotVersion = "2026.1.16"' against "$OVERLAY_FILE".

@cubic-dev-ai cubic-dev-ai Bot 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.

1 issue found across 21 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="spec/upgrade_overlays_spec.sh">

<violation number="1" location="spec/upgrade_overlays_spec.sh:60">
P2: Dependency-missing test is environment-dependent: PATH includes system dirs so real gh/jq/nix binaries satisfy the check, making the failure assertion flaky</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

#!/usr/bin/env bash
set -euo pipefail
# Override PATH to exclude tools
export PATH="/usr/bin:/bin"

@cubic-dev-ai cubic-dev-ai Bot Jan 19, 2026

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.

P2: Dependency-missing test is environment-dependent: PATH includes system dirs so real gh/jq/nix binaries satisfy the check, making the failure assertion flaky

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At spec/upgrade_overlays_spec.sh, line 60:

<comment>Dependency-missing test is environment-dependent: PATH includes system dirs so real gh/jq/nix binaries satisfy the check, making the failure assertion flaky</comment>

<file context>
@@ -0,0 +1,322 @@
+#!/usr/bin/env bash
+set -euo pipefail
+# Override PATH to exclude tools
+export PATH="/usr/bin:/bin"
+
+check_dependencies() {
</file context>
Fix with Cubic

@shunkakinoki
shunkakinoki disabled auto-merge January 19, 2026 21:59
@shunkakinoki
shunkakinoki merged commit 3fa42f7 into main Jan 19, 2026
37 of 38 checks passed
@shunkakinoki
shunkakinoki deleted the feat-make-upgrade branch January 19, 2026 23:30
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.

2 participants