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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
6 changes: 5 additions & 1 deletion .claude/settings.local.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"allow": [
"Bash(make:*)",
Expand Down Expand Up @@ -209,7 +210,10 @@
"mcp__filesystem__edit_file",
"mcp__github__get_issue",
"Bash(git reset:*)",
"Bash(periphery scan:*)"
"Bash(periphery scan:*)",
"Bash(vercel deploy:*)",
"Bash(./scripts/get_vercel_project_ids.sh:*)",
"Bash(python scripts/update_navigation_error_menu.py:*)"
],
"deny": []
},
Expand Down
68 changes: 34 additions & 34 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -3,55 +3,55 @@
# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners

# Default owners for everything in the repo
* @griffinradcliffe
* @DrunkOnJava

# iOS/Swift specific files
*.swift @griffinradcliffe
*.storyboard @griffinradcliffe
*.xib @griffinradcliffe
*.xcodeproj/ @griffinradcliffe
*.xcworkspace/ @griffinradcliffe
*.swift @DrunkOnJava
*.storyboard @DrunkOnJava
*.xib @DrunkOnJava
*.xcodeproj/ @DrunkOnJava
*.xcworkspace/ @DrunkOnJava

# Module ownership
/Modules/Core/ @griffinradcliffe
/Modules/Items/ @griffinradcliffe
/Modules/Locations/ @griffinradcliffe
/Modules/Premium/ @griffinradcliffe
/Modules/TestUtilities/ @griffinradcliffe
/Modules/Core/ @DrunkOnJava
/Modules/Items/ @DrunkOnJava
/Modules/Locations/ @DrunkOnJava
/Modules/Premium/ @DrunkOnJava
/Modules/TestUtilities/ @DrunkOnJava

# Configuration files
Package.swift @griffinradcliffe
Package.resolved @griffinradcliffe
Gemfile @griffinradcliffe
Gemfile.lock @griffinradcliffe
Makefile @griffinradcliffe
Package.swift @DrunkOnJava
Package.resolved @DrunkOnJava
Gemfile @DrunkOnJava
Gemfile.lock @DrunkOnJava
Makefile @DrunkOnJava

# CI/CD and automation
/.github/ @griffinradcliffe
/fastlane/ @griffinradcliffe
/scripts/ @griffinradcliffe
/.github/ @DrunkOnJava
/fastlane/ @DrunkOnJava
/scripts/ @DrunkOnJava

# Documentation
*.md @griffinradcliffe
/docs/ @griffinradcliffe
*.md @DrunkOnJava
/docs/ @DrunkOnJava

# Security-sensitive files (require extra attention)
*.plist @griffinradcliffe
*.entitlements @griffinradcliffe
/.env* @griffinradcliffe
/secrets/ @griffinradcliffe
*.plist @DrunkOnJava
*.entitlements @DrunkOnJava
/.env* @DrunkOnJava
/secrets/ @DrunkOnJava

# Test files (can have relaxed review)
*Tests.swift @griffinradcliffe
*Test.swift @griffinradcliffe
/Tests/ @griffinradcliffe
*UITests.swift @griffinradcliffe
*Tests.swift @DrunkOnJava
*Test.swift @DrunkOnJava
/Tests/ @DrunkOnJava
*UITests.swift @DrunkOnJava

# Dependencies (automated PRs need less strict review)
.github/dependabot.yml @griffinradcliffe
renovate.json @griffinradcliffe
.github/dependabot.yml @DrunkOnJava
renovate.json @DrunkOnJava

# Build and project files
project.yml @griffinradcliffe
.swiftlint.yml @griffinradcliffe
.swiftformat @griffinradcliffe
project.yml @DrunkOnJava
.swiftlint.yml @DrunkOnJava
.swiftformat @DrunkOnJava
23 changes: 14 additions & 9 deletions .github/sync-status/local-push.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
{
"timestamp": "2025-07-31 23:00:07 UTC",
"branch": "fix/pr-validation-check-changed-files",
"commit": "8677efd1f17264fe17c796320fac412fe9c149f1",
"message": "fix(ci): Only run Swift checks on PRs with Swift changes
"timestamp": "2025-08-01 06:28:22 UTC",
"branch": "chore/restore-protection",
"commit": "72fc5a03625ed521ef835f336b5e15c73fc6ae04",
"message": "chore: complete architecture reorganization and cleanup

- Check if PR contains Swift file changes before running SwiftLint
- Skip Swift-specific checks (TODO/FIXME, security) for non-Swift PRs
- Fixes CI failures on workflow-only PRs like #244-#248
- Reorganized Infrastructure-Storage with proper source structure
- Updated Services-Business and Services-External modules
- Enhanced Foundation layer with proper configurations
- Updated UI components and feature views
- Cleaned up Xcode project files and schemes
- Added new foundation models and core functionality
- Updated supporting files and test configurations

This properly handles PRs that only modify workflows, scripts, or
documentation without triggering Swift-related validations."
🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>"
}
114 changes: 114 additions & 0 deletions .github/workflows/commit-limits.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
name: Commit Limits

on:
pull_request:
types: [opened, synchronize, reopened]
push:
branches: [main, dev]

jobs:
lint-commits:
name: Check commit sizes and branch naming
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Check branch naming convention
if: github.event_name == 'pull_request'
run: |
branch_name="${{ github.head_ref }}"

# Define valid branch prefixes
valid_prefixes="feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert"

# Check if branch follows naming convention
if ! echo "$branch_name" | grep -E "^($valid_prefixes)/" > /dev/null; then
echo "❌ Branch name '$branch_name' doesn't follow naming convention"
echo "Branch names must start with one of: feat/, fix/, docs/, style/, refactor/, test/, chore/, perf/, ci/, build/, revert/"
exit 1
fi

echo "✅ Branch name follows convention"

- name: Check commit sizes
run: |
# For PRs, check all commits in the PR
if [ "${{ github.event_name }}" == "pull_request" ]; then
commits=$(git rev-list ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }})
else
# For pushes, just check the latest commit
commits=$(git rev-parse HEAD)
fi

failed=false

for commit in $commits; do
echo "Checking commit $commit"

# Get commit stats
files_changed=$(git diff-tree --no-commit-id --name-only -r $commit | wc -l)
lines_added=$(git diff-tree --no-commit-id --numstat -r $commit | awk '{sum+=$1} END {print sum}')
lines_deleted=$(git diff-tree --no-commit-id --numstat -r $commit | awk '{sum+=$2} END {print sum}')
Comment on lines +54 to +55
Copy link

Copilot AI Jul 31, 2025

Choose a reason for hiding this comment

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

The awk command will output an empty string when there are no lines to sum, which could cause issues in arithmetic operations. Consider adding a default value: awk '{sum+=$1} END {print sum+0}' to ensure it always outputs a number.

Suggested change
lines_added=$(git diff-tree --no-commit-id --numstat -r $commit | awk '{sum+=$1} END {print sum}')
lines_deleted=$(git diff-tree --no-commit-id --numstat -r $commit | awk '{sum+=$2} END {print sum}')
lines_added=$(git diff-tree --no-commit-id --numstat -r $commit | awk '{sum+=$1} END {print sum+0}')
lines_deleted=$(git diff-tree --no-commit-id --numstat -r $commit | awk '{sum+=$2} END {print sum+0}')

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Jul 31, 2025

Choose a reason for hiding this comment

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

The awk command will output an empty string when there are no lines to sum, which could cause issues in arithmetic operations. Consider adding a default value: awk '{sum+=$2} END {print sum+0}' to ensure it always outputs a number.

Suggested change
lines_deleted=$(git diff-tree --no-commit-id --numstat -r $commit | awk '{sum+=$2} END {print sum}')
lines_deleted=$(git diff-tree --no-commit-id --numstat -r $commit | awk '{sum+=$2} END {print sum+0}')

Copilot uses AI. Check for mistakes.
total_lines=$((lines_added + lines_deleted))
Copy link

Copilot AI Jul 31, 2025

Choose a reason for hiding this comment

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

This arithmetic operation could fail if lines_added or lines_deleted are empty strings (when commits have no changes). The variables should be validated or defaulted to 0 before this calculation.

Suggested change
total_lines=$((lines_added + lines_deleted))
total_lines=$(( ${lines_added:-0} + ${lines_deleted:-0} ))

Copilot uses AI. Check for mistakes.

echo " Files changed: $files_changed"
echo " Lines added: $lines_added"
echo " Lines deleted: $lines_deleted"
echo " Total lines changed: $total_lines"

# Check limits
if [ "$files_changed" -gt 30 ]; then
echo "❌ Commit changes too many files: $files_changed (max: 30)"
failed=true
fi

if [ "$total_lines" -gt 800 ]; then
echo "❌ Commit changes too many lines: $total_lines (max: 800)"
failed=true
fi

# Check for generated files (relaxed for initial setup)
if git diff-tree --no-commit-id --name-only -r $commit | grep -E "(Package\.resolved|\.pbxproj|\.xcodeproj)" > /dev/null; then
echo "⚠️ Warning: Commit includes generated files (allowed during setup phase)"
fi
done

if [ "$failed" = true ]; then
echo ""
echo "🚫 One or more commits exceed size limits"
echo "Please break large changes into smaller, focused commits"
exit 1
fi

echo ""
echo "✅ All commits within size limits"

- name: Check commit messages
if: github.event_name == 'pull_request'
run: |
# Check commit message format
commits=$(git rev-list ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }})

failed=false

for commit in $commits; do
message=$(git log --format=%s -n 1 $commit)

# Check conventional commit format
if ! echo "$message" | grep -E "^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\(.+\))?: .+" > /dev/null; then
echo "❌ Commit message doesn't follow conventional format: $message"
echo "Expected format: type(scope): description"
echo "Example: feat(inventory): add item search functionality"
failed=true
fi
done

if [ "$failed" = true ]; then
exit 1
fi

echo "✅ All commit messages follow convention"
124 changes: 62 additions & 62 deletions .github/workflows/pr-management.yml
Original file line number Diff line number Diff line change
Expand Up @@ -161,66 +161,66 @@ jobs:
body: comment
});

auto-merge-small-prs:
name: Auto-merge Small PRs to Dev
runs-on: ubuntu-latest
if: |
github.event_name == 'pull_request_review' &&
github.event.review.state == 'approved' &&
github.event.pull_request.base.ref == 'dev'

steps:
- name: Check Auto-merge Eligibility
uses: actions/github-script@v7
with:
script: |
const pr = context.payload.pull_request;

// Check PR size
if (pr.additions + pr.deletions > 200) {
console.log('PR too large for auto-merge');
return;
}

// Check if all checks passed
const { data: checks } = await github.rest.checks.listForRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: pr.head.sha
});

const allChecksPassed = checks.check_runs.every(
check => check.status === 'completed' && check.conclusion === 'success'
);

if (!allChecksPassed) {
console.log('Not all checks have passed');
return;
}

// Auto-merge eligible small PRs to dev
try {
await github.rest.pulls.merge({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number,
commit_title: `Auto-merge: ${pr.title}`,
commit_message: pr.body || '',
merge_method: 'squash'
});

console.log(`Successfully auto-merged PR #${pr.number}`);
} catch (error) {
console.log(`Failed to auto-merge: ${error.message}`);

// Post comment about why auto-merge failed
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
body: `🤖 Auto-merge was attempted but failed. Please merge manually.\n\nError: ${error.message}`
});
}
# auto-merge-small-prs:
# name: Auto-merge Small PRs to Dev
# runs-on: ubuntu-latest
# if: |
# github.event_name == 'pull_request_review' &&
# github.event.review.state == 'approved' &&
# github.event.pull_request.base.ref == 'dev'
#
# steps:
# - name: Check Auto-merge Eligibility
# uses: actions/github-script@v7
# with:
# script: |
# const pr = context.payload.pull_request;
#
# // Check PR size
# if (pr.additions + pr.deletions > 200) {
# console.log('PR too large for auto-merge');
# return;
# }
#
# // Check if all checks passed
# const { data: checks } = await github.rest.checks.listForRef({
# owner: context.repo.owner,
# repo: context.repo.repo,
# ref: pr.head.sha
# });
#
# const allChecksPassed = checks.check_runs.every(
# check => check.status === 'completed' && check.conclusion === 'success'
# );
#
# if (!allChecksPassed) {
# console.log('Not all checks have passed');
# return;
# }
#
# // Auto-merge eligible small PRs to dev
# try {
# await github.rest.pulls.merge({
# owner: context.repo.owner,
# repo: context.repo.repo,
# pull_number: pr.number,
# commit_title: `Auto-merge: ${pr.title}`,
# commit_message: pr.body || '',
# merge_method: 'squash'
# });
#
# console.log(`Successfully auto-merged PR #${pr.number}`);
# } catch (error) {
# console.log(`Failed to auto-merge: ${error.message}`);
#
# // Post comment about why auto-merge failed
# await github.rest.issues.createComment({
# owner: context.repo.owner,
# repo: context.repo.repo,
# issue_number: pr.number,
# body: `🤖 Auto-merge was attempted but failed. Please merge manually.\n\nError: ${error.message}`
# });
# }

conflict-detection:
name: Detect Merge Conflicts
Expand Down Expand Up @@ -281,8 +281,8 @@ jobs:
uses: actions/github-script@v7
with:
script: |
const daysUntilStale = 7;
const daysUntilClose = 14;
const daysUntilStale = 10;
const daysUntilClose = 30;
const staleLabel = 'stale';

const { data: pullRequests } = await github.rest.pulls.list({
Expand Down
Loading
Loading