Skip to content
Open
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
41 changes: 41 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,24 @@ jobs:
echo "has_firmware=$(echo "$FILES" | grep -qE '^(omi|omiGlass)/.*\.(c|cpp|cc|cxx|h|hpp)$' && echo true || echo false)" >> $GITHUB_OUTPUT
echo "has_frontend=$(echo "$FILES" | grep -q '^web/frontend/' && echo true || echo false)" >> $GITHUB_OUTPUT
echo "has_personas=$(echo "$FILES" | grep -q '^web/personas-open-source/' && echo true || echo false)" >> $GITHUB_OUTPUT
# Also run the Rust check when this workflow changes so CI PRs dogfood
# the new guard instead of only validating YAML syntax.
echo "has_desktop_rust=$(echo "$FILES" | grep -qE '^desktop/macos/Backend-Rust/|^\.github/workflows/lint\.yml$' && echo true || echo false)" >> $GITHUB_OUTPUT

# -- Universal source hygiene --
- name: Check merge conflict markers
run: |
failed=0
while IFS= read -r file; do
if [ -f "$file" ] && grep -I -nE '^(<<<<<<<|>>>>>>>)' "$file"; then
failed=1
fi
done < /tmp/changed-files.txt

if [ "$failed" -eq 1 ]; then
echo "FAIL: unresolved merge conflict markers found in changed files"
exit 1
fi

# -- Dart --
- name: Setup Flutter
Expand Down Expand Up @@ -103,6 +121,29 @@ jobs:
echo "$FILES" | xargs clang-format --dry-run --Werror
fi

# -- Desktop Rust backend --
- name: Cache desktop Rust backend build
if: steps.changed.outputs.has_desktop_rust == 'true'
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
desktop/macos/Backend-Rust/target
key: ${{ runner.os }}-desktop-rust-${{ hashFiles('desktop/macos/Backend-Rust/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-desktop-rust-

- name: Check desktop Rust backend
if: steps.changed.outputs.has_desktop_rust == 'true'
run: |
FILES=$(grep -E '^desktop/macos/Backend-Rust/.*\.rs$' /tmp/changed-files.txt || true)
if [ -n "$FILES" ]; then
echo "$FILES" | xargs rustfmt --edition 2021 --check

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: The CI rustfmt invocation is not path-safe: xargs splits filenames on whitespace, so changed Rust files with spaces in their path will break formatting checks.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/lint.yml, line 142:

<comment>The CI rustfmt invocation is not path-safe: `xargs` splits filenames on whitespace, so changed Rust files with spaces in their path will break formatting checks.</comment>

<file context>
@@ -139,7 +139,7 @@ jobs:
           FILES=$(grep -E '^desktop/macos/Backend-Rust/.*\.rs$' /tmp/changed-files.txt || true)
           if [ -n "$FILES" ]; then
-            echo "$FILES" | xargs rustfmt --check
+            echo "$FILES" | xargs rustfmt --edition 2021 --check
           fi
           cd desktop/macos/Backend-Rust
</file context>
Suggested change
echo "$FILES" | xargs rustfmt --edition 2021 --check
printf '%s\n' "$FILES" | while IFS= read -r file; do rustfmt --edition 2021 --check "$file"; done
Fix with cubic

fi
cd desktop/macos/Backend-Rust
cargo check --locked

# -- Frontend --
- name: Setup Node.js
if: steps.changed.outputs.has_frontend == 'true' || steps.changed.outputs.has_personas == 'true'
Expand Down
50 changes: 50 additions & 0 deletions scripts/pre-commit
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
#!/bin/sh

# Universal source hygiene: fail fast on unresolved merge conflict markers.
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM)

if [ -n "$STAGED_FILES" ]; then
conflict_found=0
while IFS= read -r file; do
[ -n "$file" ] || continue
if git grep --cached -n -I -E '^(<<<<<<<|>>>>>>>)' -- "$file"; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Re-scan conflict markers after staging formatter output

This checks only the cached index before the hook's later formatter blocks mutate the index with git add, so a partially staged firmware file can still commit markers: stage a clean hunk in omi/*.c, leave an unstaged <<<<<<< hunk, and the later clang-format -i/git add path stages the whole file after this scan has already passed (I checked clang-format exits 0 and leaves that marker line intact). Move this scan to the end or rerun it after every formatter has re-staged files.

Useful? React with 👍 / 👎.

conflict_found=1
fi
done <<EOF
$STAGED_FILES
EOF

if [ "$conflict_found" -eq 1 ]; then
echo "Unresolved merge conflict markers found in staged files" >&2
exit 1
fi
fi

# Dart formatting for app/
STAGED_DART_FILES=$(git diff --cached --name-only --diff-filter=ACM "app/**.dart" | grep -v -e '\.gen\.dart$' -e '\.g\.dart$')

Expand Down Expand Up @@ -79,4 +99,34 @@ if [ -n "$STAGED_C_FILES" ]; then
echo "$STAGED_C_FILES" | xargs git add
fi

# Rust formatting/checking for desktop backend.
STAGED_DESKTOP_RUST_INPUTS=$(git diff --cached --name-only --diff-filter=ACM | grep -E '^desktop/macos/Backend-Rust/' || true)
STAGED_DESKTOP_RUST_FILES=$(printf '%s\n' "$STAGED_DESKTOP_RUST_INPUTS" | grep -E '\.rs$' || true)

if [ -n "$STAGED_DESKTOP_RUST_INPUTS" ]; then
echo "Checking desktop Rust backend..."
if ! command -v cargo >/dev/null 2>&1; then
echo "cargo is not installed. Please install Rust/Cargo first" >&2
exit 1
fi
if [ -n "$STAGED_DESKTOP_RUST_FILES" ]; then
while IFS= read -r file; do
[ -n "$file" ] || continue
if ! rustfmt --edition 2021 "$file"; then
echo "rustfmt failed for $file" >&2
exit 1
fi
git add "$file"
done <<EOF
$STAGED_DESKTOP_RUST_FILES
EOF
fi
if ! (
cd desktop/macos/Backend-Rust && \
cargo check --locked
); then
exit 1
fi
fi

exit 0
Loading