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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Force LF line endings for shell scripts (required for Linux/macOS compatibility)
*.sh text eol=lf
*.bats text eol=lf
*.bash text eol=lf
hooks/pre-commit text eol=lf

# Text files — normalize to LF
Expand Down
27 changes: 27 additions & 0 deletions .github/workflows/branch-protection.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,30 @@ jobs:
- name: Check shell formatting (shfmt)
run: shfmt -d -i 2 -ci scripts/
continue-on-error: true

test:
name: Run Test Suite
runs-on: ubuntu-latest
needs: lint

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Install bats-core and helpers
run: |
git clone --depth 1 --branch v1.13.0 https://github.com/bats-core/bats-core.git /tmp/bats
sudo /tmp/bats/install.sh /usr/local
git clone --depth 1 --branch v0.3.0 https://github.com/bats-core/bats-support.git /tmp/bats-support
git clone --depth 1 --branch v2.2.4 https://github.com/bats-core/bats-assert.git /tmp/bats-assert

Comment on lines +88 to +94
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The workflow installs bats via git clone --depth 1 from default branches. That’s brittle (upstream changes can break CI unexpectedly) and increases supply-chain risk compared to pinning versions.

This is especially relevant since branch protection will depend on these checks.

Suggestion

Pin bats-core/bats-support/bats-assert to tags or commit SHAs, or switch to a maintained action (e.g. bats-core/bats-action) with version pinning.

Reply with "@CharlieHelps yes please" if you want me to add a commit that pins these dependencies (either via tags/SHAs or an action).

- name: Configure git identity for test repos
run: |
git config --global user.email "ci@example.com"
git config --global user.name "CI Test"

- name: Run unit tests
run: bats tests/unit/

- name: Run integration tests
run: bats tests/integration/
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
logs/
*.log
.cgw.conf
CLAUDE.md
SESSION_LOG.md
.claude/commands/
.claude/skills/
5 changes: 5 additions & 0 deletions .shellcheckrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# shellcheck configuration — matches CI invocation in branch-protection.yml
# Enables source-following (-x) and sets source path so local runs
# produce the same results as: shellcheck -x --source-path=scripts/git
external-sources=true
source-path=scripts/git
71 changes: 69 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ No manual config editing required for common setups. `configure.sh` auto-detects
| `validate_branches.sh` | Check branch state before operations |
| `check_lint.sh` | Read-only lint validation |
| `fix_lint.sh` | Auto-fix lint issues |
| `create_pr.sh` | Create GitHub PR from source → target (triggers Charlie CI + GitHub Actions) |
| `install_hooks.sh` | Install git pre-commit hooks |

---
Expand Down Expand Up @@ -106,6 +107,21 @@ Add project-specific prefixes via `CGW_EXTRA_PREFIXES="cuda|tensorrt"` in `.cgw.

---

## Branch Setup (one-time)

CGW uses a two-branch model. Create `development` before starting work:

```bash
git checkout -b development
git push -u origin development
```

> **Note:** `git push -u origin development` above is a one-time bootstrap exception — CGW isn't configured yet at this point so the wrapper scripts aren't available. All subsequent pushes should use `./scripts/git/push_validated.sh`.

Keep `main` as the GitHub default branch. Charlie reads its config from the default branch.

---

## Common Operations

### Commit with lint validation
Expand All @@ -121,13 +137,25 @@ Add project-specific prefixes via `CGW_EXTRA_PREFIXES="cuda|tensorrt"` in `.cgw.
./scripts/git/commit_enhanced.sh --non-interactive "feat: add feature"
```

### Merge to target branch
### Merge to target branch (direct)

```bash
./scripts/git/merge_with_validation.sh --dry-run # preview
./scripts/git/merge_with_validation.sh --dry-run # preview
./scripts/git/merge_with_validation.sh --non-interactive # execute
```

### Create PR (triggers Charlie CI + GitHub Actions)

```bash
./scripts/git/create_pr.sh --dry-run # preview title + commits
./scripts/git/create_pr.sh # interactive — confirm title
./scripts/git/create_pr.sh --non-interactive # accept auto-generated title
./scripts/git/create_pr.sh --draft # open as draft (skip auto-review)
```

Requires: `gh` CLI installed and authenticated (`gh auth login`).
Set `CGW_MERGE_MODE="pr"` in `.cgw.conf` to use PRs by default.

### Push

```bash
Expand Down Expand Up @@ -248,11 +276,50 @@ Legacy `CLAUDE_GIT_*` variables are still supported:
- git 2.0+
- For lint: ruff / eslint / golangci-lint (or none — set `CGW_LINT_CMD=""`)
- For Claude Code integration: Claude Code CLI
- For PR creation (`create_pr.sh`): [gh CLI](https://cli.github.com/) + `gh auth login`

Compatible with: Linux, macOS, Windows (Git Bash / WSL)

---

## CI & Code Quality

### GitHub Actions

| Workflow | Trigger | Checks |
|----------|---------|--------|
| Branch Protection | Push/PR to `development`, `main` | Local-only file detection, `.gitattributes` presence, ShellCheck, shfmt format |
| Docs Validation | Changes to `*.md` files | Markdown linting, broken links, spelling |

### Charlie CI Agent

This project uses [Charlie](https://charlielabs.ai) for AI-assisted code review on pull requests.

```yaml
# .charlie/config.yml
checkCommands:
fix: shfmt -w -i 2 -ci scripts/ # auto-format after edits
lint: shellcheck scripts/git/*.sh # static analysis
```

**Setup** (repository admin): Install the `charliecreates` GitHub App and invite `@CharlieHelps` as a repository collaborator (Triage role minimum).

### Local Tool Installation

```bash
# macOS
brew install shellcheck shfmt

# Ubuntu/Debian
sudo apt-get install shellcheck
# shfmt: https://github.com/mvdan/sh/releases

# Windows (scoop)
scoop install shellcheck shfmt
```

---

## License

MIT — see [LICENSE](LICENSE)
17 changes: 17 additions & 0 deletions cgw.conf.example
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,20 @@ CGW_CLEANUP_TESTS="0"
# for force-push. Defaults to CGW_TARGET_BRANCH if not set.

# CGW_PROTECTED_BRANCHES="main staging"

# ============================================================================
# MERGE MODE
# ============================================================================
# Controls how changes are promoted from source to target branch.
#
# "direct" (default): merge locally via merge_with_validation.sh.
# Fast, no PR required.
#
# "pr": create a GitHub PR via create_pr.sh.
# Triggers Charlie CI auto-review + GitHub Actions.
# Requires: gh CLI installed + authenticated.
#
# Use "pr" to enable CI agent review before merging to main.
#
CGW_MERGE_MODE="direct"
# CGW_MERGE_MODE="pr"
49 changes: 45 additions & 4 deletions command/auto-git-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,23 @@ git log -1 --format="%h %s"

---

### Phase 4: Merge to Target Branch
### Phase 4: Merge or PR

**Step 4.1: Run merge with validation**
Check `CGW_MERGE_MODE` (or ask user preference):

```bash
echo "${CGW_MERGE_MODE:-direct}"
```

**If `CGW_MERGE_MODE=direct` (default):** → Follow Phase 4A (direct merge)

**If `CGW_MERGE_MODE=pr`:** → Follow Phase 4B (create PR, stop — CI takes over)

---

#### Phase 4A: Direct Merge to Target Branch

**Step 4A.1: Run merge with validation**

```bash
./scripts/git/merge_with_validation.sh --non-interactive
Expand All @@ -147,7 +161,34 @@ git log -1 --format="%h %s"

---

### Phase 5: Push Target Branch
#### Phase 4B: Create PR (triggers Charlie CI + GitHub Actions)

**Step 4B.1: Create pull request**

```bash
./scripts/git/create_pr.sh --non-interactive
```

- If exit code 0: PR created — workflow ends here (CI + Charlie review the PR)
- If exit code ≠ 0: Run without `--non-interactive` to see error

**Step 4B.2: Return to source branch**

```bash
git checkout "${CGW_SOURCE_BRANCH:-development}" >/dev/null 2>&1
```

**Final Report (PR mode):**
```
Workflow complete (PR mode)

Source branch: [hash] "[message]" pushed
PR: [url] — awaiting Charlie CI review
```

---

### Phase 5: Push Target Branch (direct mode only)

**Step 5.1: Push target branch (suppress output)**

Expand All @@ -166,7 +207,7 @@ git checkout "${CGW_SOURCE_BRANCH:-development}" >/dev/null 2>&1

---

### Final Report
### Final Report (direct mode)

```bash
git log "${CGW_SOURCE_BRANCH:-development}" -1 --format="%h %s"
Expand Down
Loading
Loading