Files
git-incron-deploy/.github/copilot-instructions.md

199 lines
8.2 KiB
Markdown

# Copilot Instructions for git-incron-deploy
## Project Overview
**git-incron-deploy** is a lightweight auto-deployment system that uses `incron` (file system event monitoring) to automatically pull and deploy code from remote git repositories when triggered. It's designed for keeping development and production systems synchronized with git commits without manual intervention.
## Architecture & Data Flow
### Core Mechanism
1. **Trigger Event**: External webhook (PHP/shell script) creates `git.flag` file in monitored directory
2. **incron Detection**: `incron` watches directory for `IN_CREATE` events (new file creation)
3. **Script Execution**: `git.sh` automatically runs on flag detection
4. **Git Sync**: Script performs `git fetch --all` and `git reset --hard origin/<branch>` to sync code
5. **Permissions**: Resets ownership to `www-data:www-data` for web server access
6. **Cleanup**: Removes `git.flag` to prevent re-triggering
### Configuration Files
- **incron.d/www-deploy**: Incron watch rule defining the directory, trigger event, script path, and branch
- **bitbucket-pipelines.yml**: CI/CD integration for automated testing (example shows deployment via calling git.sh)
- **example-trigger/**: Sample webhook implementations (PHP and shell) that create the flag file
## Key Developer Patterns
### Flag-Based Triggering
The system relies on file creation as a signal. Cannot monitor non-existent files directly, so `git.flag` must be created by external triggers. This is intentional - incron cannot watch for file creation of files that don't exist yet.
### Script Parameters
`git.sh` accepts three required parameters:
```bash
./git.sh <folder> <file> <branch>
# Example: ./git.sh /var/www www-deploy master
# $1: deployment folder path
# $2: expected filename trigger (must be "git.flag")
# $3: branch to deploy from remote
```
### Branch Specification
Different branches can be deployed to different directories. Common pattern:
- `/var/www` → production branch (often `master`)
- `/var/www-dev` → development branch (often `dev` or `testing`)
- Each monitored directory gets its own incron rule with branch specified
### Permission Handling
After git operations, script forces `www-data:www-data` ownership recursively. This is required because git operations may pull files owned by different users.
## Integration Points
### External Triggers
Two example implementations provided:
1. **PHP**: `touch("git.flag")` - Lightweight, suitable for webhook endpoints
2. **Shell**: `touch git.flag` - Useful for cron jobs or manual scripts
These are typically called from:
- GitLab/Bitbucket webhooks (configured to POST to your endpoint)
- External monitoring systems
- Manual deployment scripts
### Slack Integration
Script calls `slackecho` function (user-implemented) for deployment notifications. The function is referenced but not defined in repo - implementer must provide their own notification wrapper.
**Implementation Pattern**: Define `slackecho` as a bash function in your deployment environment or as a sourced script:
```bash
# Example function to add to your shell environment
slackecho() {
local message="$1"
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"$message\"}" \
https://hooks.slack.com/services/YOUR/WEBHOOK/URL
}
export -f slackecho
```
Or wrap deployment calls to capture output:
```bash
slackecho "Deploying to $1"
# ... deployment commands ...
slackecho "Completed"
```
The function receives human-readable messages identifying the deployment target and completion status. This allows operators to monitor deployments in real-time across multiple environments.
## Deployment Workflow
### Setup Checklist
1. Clone git repo with pre-authentication configured (SSH key or git credentials)
2. Make `git.sh` executable: `chmod +x git.sh`
3. Install incron: `apt-get install incron` (Linux/Debian systems)
4. Copy incron rule to `/etc/incron.d/www-deploy`, adjust paths and branch
5. Set up external trigger (webhook or cron) to create `git.flag`
### Manual Trigger (Debugging)
```bash
# To manually trigger deployment without webhook
touch git.flag
# incron will detect this and run git.sh
```
### Testing via Bitbucket Pipelines
The pipeline runs: `chmod +x` followed by calling `git.sh` with test parameters. This validates the script works in CI environment.
### Incron Rule Configuration Syntax
Incron rules are stored in `/etc/incron.d/` with the format:
```
<path> <events> <script> <arguments>
```
**Production example** (from incron.d/www-deploy):
```
/var/www/ IN_CREATE /var/www/git.sh $@ $# master
```
- `/var/www/` - Directory to monitor
- `IN_CREATE` - Only trigger on file creation events
- `/var/www/git.sh` - Absolute path to deployment script
- `$@` - Full path and name of the file (passed to git.sh as $2)
- `$#` - Inode number (unused but included)
- `master` - Branch name (passed to git.sh as $3)
**Development example** (for dev branch):
```
/var/www-dev/ IN_CREATE /var/www-dev/git.sh $@ $# dev
```
**Key incron event types**:
- `IN_CREATE` - File/directory created
- `IN_DELETE` - File/directory deleted
- `IN_MODIFY` - File modified
- `IN_ATTRIB` - Attributes changed
For this project, always use `IN_CREATE` to detect new trigger files.
## Troubleshooting Common Issues
### Permission Denied Errors
**Symptom**: Deployment fails with "Permission denied" when executing git.sh
**Causes & Solutions**:
1. Script not executable: `chmod +x git.sh` on the deployment server
2. Running user lacks permissions: Ensure incron daemon runs as root or appropriate user (check `/etc/default/incron`)
3. Target directory not writable: Verify the directory path is writable by the incron process
**Debug**: Run manually:
```bash
./git.sh /var/www git.flag master # Should execute without errors
```
### Git Authentication Failures
**Symptom**: "Permission denied (publickey)" or "Repository not found"
**Causes & Solutions**:
1. SSH keys not loaded: Incron doesn't inherit parent shell SSH keys. Configure SSH keys for the incron/www-data user:
```bash
ssh-keygen -t rsa -f /home/incron/.ssh/id_rsa # For incron user
ssh-keygen -t rsa -f /var/www/.ssh/id_rsa # For www-data user
```
2. SSH known_hosts not populated: Pre-authenticate once manually:
```bash
sudo -u www-data ssh -o StrictHostKeyChecking=no git@bitbucket.org
```
3. Git credentials not available: Use `.netrc` file or git credential helper configured for the deployment user
**Debug**: Test git operations as the incron user:
```bash
cd /var/www
sudo -u www-data git fetch --all
```
### Deployment Not Triggering
**Symptom**: Touching git.flag manually doesn't trigger deployment
**Causes & Solutions**:
1. Incron not running: `sudo systemctl status incron` or `sudo service incron status`
2. Incron rule syntax invalid: Test with `sudo incrontab -l` to view loaded rules
3. Directory path incorrect: Paths in incron rules must be absolute and must end with `/` for directory watching
4. File doesn't match trigger condition: The rule checks `$2` (filename) equals `git.flag` - ensure trigger creates exactly that filename
**Debug**: Monitor incron logs:
```bash
tail -f /var/log/syslog | grep incron # Debian/Ubuntu
tail -f /var/log/messages | grep incron # RedHat/CentOS
```
### Ownership/Permission Issues After Deployment
**Symptom**: Web server can't read deployed files after git.sh runs
**Causes & Solutions**:
1. `chown` not running as root: git.sh must execute with sufficient privileges. If running as www-data, it cannot change ownership
2. Non-www-data deployment user: Modify the ownership line in git.sh to match your web server user (e.g., `apache:apache`, `nginx:nginx`)
**Verification**:
```bash
ls -la /var/www/ | head -5 # Check file ownership
```
## Important Notes
- **System Dependencies**: Requires `incron` package and file system event monitoring - Linux/Unix only
- **Pre-authentication**: Repository must be cloned with pre-configured SSH keys or git credentials to allow unattended pulls
- **Ownership Critical**: Web server must own deployed files for proper execution
- **Single-Branch Limitation**: Each monitored directory watches for one specific branch (multiple directories needed for multiple branches)
- **No Locking**: No distributed locking mechanism - concurrent triggers could cause race conditions