cascade-cli 0.1.152

Stacked diffs CLI for Bitbucket Server
Documentation
---
description: 
globs: 
alwaysApply: true
---
# CI Compatibility Guide

## Cross-Platform Development

Cascade CLI supports and is tested on **Ubuntu, Windows, and macOS**. This guide covers critical compatibility considerations.

## Common CI Failures and Solutions

### 1. Rust Lifetime Annotation Errors (Ubuntu)

**Issue**: Ubuntu CI failing with lifetime syntax errors for git2 objects.

**Error Example**:
```
error: lifetime flowing from input to output with different syntax can be confusing
```

**Solution**: Use explicit lifetime annotations for git2 objects in [src/git/repository.rs](mdc:src/git/repository.rs):

```rust
// ✅ CORRECT - Explicit lifetimes
pub fn get_head_commit(&self) -> Result<git2::Commit<'_>>
pub fn get_commit(&self, commit_hash: &str) -> Result<git2::Commit<'_>>
pub fn get_signature(&self) -> Result<Signature<'_>>
```

### 2. Unused Variable Errors (Windows)

**Issue**: Windows CI failing due to platform-specific unused variables.

**Error Example**:
```
error: unused variable: `permissions`
```

**Solution**: Scope variables inside conditional compilation blocks:

```rust
// ✅ CORRECT - Variable scoped to where it's used
#[cfg(unix)]
{
    use std::os::unix::fs::PermissionsExt;
    let permissions = metadata.permissions();
    assert!(permissions.mode() & 0o111 != 0);
}
```

### 3. Environment-Dependent Test Failures

**Issue**: Tests assuming specific Git configurations failing in CI.

**Error Example**: Test expecting "master" branch fails when CI uses "main".

**Solution**: Make tests environment-agnostic:

```rust
// ❌ BAD - Hardcoded branch name
assert!(branch_info.iter().any(|b| b.name == "master"));

// ✅ GOOD - Environment-agnostic
let current_branch = repo.head().unwrap().shorthand().unwrap();
assert!(branch_info.iter().any(|b| b.name == current_branch));
```

## Platform-Specific Code Patterns

### File Permissions
Only validate executable permissions on Unix systems:

```rust
#[cfg(unix)]
{
    use std::os::unix::fs::PermissionsExt;
    let permissions = metadata.permissions();
    assert!(permissions.mode() & 0o111 != 0);
}

#[cfg(windows)]
{
    // Windows doesn't have executable bits
    // Alternative validation if needed
}
```

### Path Handling
Always use cross-platform path operations:

```rust
// ✅ CORRECT - Cross-platform
use std::path::PathBuf;
let path = base_path.join("subdir").join("file.txt");

// ❌ WRONG - Unix-specific
let path = format!("{}/subdir/file.txt", base_path);
```

### Command Execution
Handle platform differences in shell commands:

```rust
#[cfg(windows)]
let output = Command::new("cmd")
    .args(["/C", "git", "status"])
    .output()?;

#[cfg(not(windows))]
let output = Command::new("git")
    .args(["status"])
    .output()?;
```

## Git Configuration Differences

### Default Branch Names
Different Git versions and CI environments use different default branch names:

- **Legacy Git**: "master"
- **Modern Git/GitHub**: "main" 
- **Custom setups**: Can be anything

**Solution**: Always query the current branch dynamically:

```rust
fn get_default_branch(repo: &git2::Repository) -> Result<String> {
    let head = repo.head()?;
    let branch_name = head.shorthand()
        .ok_or("Could not get branch name")?
        .to_string();
    Ok(branch_name)
}
```

### Git User Configuration
CI environments may lack git user configuration:

```rust
// Ensure git user is configured for tests
Command::new("git")
    .args(["config", "user.name", "Test User"])
    .current_dir(&repo_path)
    .output()?;
    
Command::new("git")
    .args(["config", "user.email", "test@example.com"])
    .current_dir(&repo_path)
    .output()?;
```

## MSRV (Minimum Supported Rust Version)

**Current MSRV**: Rust 1.82.0 (specified in [Cargo.toml](mdc:Cargo.toml))

### Dependency Compatibility
Some dependencies require newer Rust versions:
- Monitor `cargo check` output for MSRV violations
- Update MSRV in both [Cargo.toml](mdc:Cargo.toml) and CI workflows
- Update documentation when MSRV changes

## CI Workflow Configuration

### GitHub Actions Matrix
The project uses matrix builds for cross-platform testing:

```yaml
strategy:
  matrix:
    os: [ubuntu-latest, windows-latest, macos-latest]
    rust: [1.82.0, stable]
```

### Platform-Specific Steps
Some CI steps are conditional:

```yaml
- name: Install dependencies (Ubuntu)
  if: matrix.os == 'ubuntu-latest'
  run: sudo apt-get update && sudo apt-get install -y build-essential
```

## Testing in CI Environments

### Environment Limitations
- **Network access**: May be restricted
- **File system**: Different permissions and case sensitivity
- **Git configuration**: May be minimal or non-standard
- **External dependencies**: May not be available

### Robust Test Design
```rust
#[test]
fn test_with_fallback() {
    let result = some_operation();
    
    // Primary assertion
    if let Ok(value) = result {
        assert_eq!(value, expected);
    } else {
        // Fallback for CI environments
        println!("Operation not available in CI environment");
    }
}
```

## Pre-Push Validation

The [scripts/pre-push-check.sh](mdc:scripts/pre-push-check.sh) replicates CI checks locally:

- Helps catch platform-specific issues before push
- Includes environment awareness warnings
- Runs same commands as CI workflows

**Limitation**: Cannot catch all environment-dependent issues (like default Git branch differences).

## Troubleshooting CI Failures

### 1. Check Platform Specifics
- Review the failing OS (Ubuntu/Windows/macOS)
- Look for platform-specific error patterns
- Check conditional compilation usage

### 2. Reproduce Locally
```bash
# Test with different Git configurations
git config --global init.defaultBranch main  # or master
./scripts/pre-push-check.sh
```

### 3. Use CI Debug Mode
Add debug output to CI workflows:
```yaml
- name: Debug Git Configuration
  run: |
    git --version
    git config --list
    git branch -a
```

### 4. Review Recent Changes
- Check for new platform-specific code
- Look for hardcoded assumptions
- Verify conditional compilation blocks