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

8.2 KiB

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:

./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:

# 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:

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)

# 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:

./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:
    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:
    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:

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:

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:

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