{"id":37228502,"url":"https://github.com/gedex/ngenteni","last_synced_at":"2026-01-15T03:28:03.849Z","repository":{"id":331828065,"uuid":"1132046819","full_name":"gedex/ngenteni","owner":"gedex","description":"Git Repository Watcher","archived":false,"fork":false,"pushed_at":"2026-01-11T12:32:29.000Z","size":18,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"trunk","last_synced_at":"2026-01-11T14:21:39.544Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gedex.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-11T07:57:18.000Z","updated_at":"2026-01-11T12:30:19.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/gedex/ngenteni","commit_stats":null,"previous_names":["gedex/ngenteni"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/gedex/ngenteni","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gedex%2Fngenteni","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gedex%2Fngenteni/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gedex%2Fngenteni/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gedex%2Fngenteni/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gedex","download_url":"https://codeload.github.com/gedex/ngenteni/tar.gz/refs/heads/trunk","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gedex%2Fngenteni/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28442273,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-15T00:55:22.719Z","status":"online","status_checked_at":"2026-01-15T02:00:08.019Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-15T03:28:03.280Z","updated_at":"2026-01-15T03:28:03.836Z","avatar_url":"https://github.com/gedex.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ngenteni - Git Repository Watcher\n\n[![Tests](https://github.com/gedex/ngenteni/actions/workflows/test.yml/badge.svg)](https://github.com/gedex/ngenteni/actions/workflows/test.yml)\n\nA simple Git repository watcher that monitors remote repositories for new commits and executes commands when changes are detected.\n\n**Ngenteni** (Javanese: \"waiting\") - A lightweight tool that watches your Git repositories.\n\n## Features\n\n- Monitor multiple remote Git repositories simultaneously\n- Configurable polling intervals per repository\n- Execute custom commands when new commits are detected\n- Pass repository information via environment variables\n- Automatic repository cloning and fetching\n\n## Installation\n\n### Download Pre-built Binaries\n\nDownload the latest release for your platform from the [releases page](https://github.com/gedex/ngenteni/releases).\n\n#### Linux/macOS\n```bash\n# Download and extract (replace VERSION and OS/ARCH with your values)\nwget https://github.com/gedex/ngenteni/releases/download/v0.1.0/ngenteni_0.1.0_Linux_x86_64.tar.gz\ntar -xzf ngenteni_0.1.0_Linux_x86_64.tar.gz\nsudo mv ngenteni /usr/local/bin/\n```\n\n#### Windows\nDownload the `.zip` file for Windows from the releases page and extract it.\n\n### Using Go Install\n\n```bash\ngo install github.com/gedex/ngenteni@latest\n```\n\n### Build from Source\n\n```bash\ngit clone https://github.com/gedex/ngenteni.git\ncd ngenteni\ngo build -o ngenteni main.go\n```\n\n## Configuration\n\nCreate a `config.json` file with your repositories:\n\n```json\n{\n  \"repos\": [\n    {\n      \"name\": \"my-project\",\n      \"url\": \"https://github.com/username/my-project.git\",\n      \"branch\": \"main\",\n      \"interval\": \"30s\",\n      \"command\": \"echo 'New commit detected!'\",\n      \"workdir\": \"./repos\"\n    }\n  ]\n}\n```\n\n### Configuration Fields\n\n- **name**: Unique identifier for the repository\n- **url**: Git repository URL (HTTPS or SSH)\n- **branch**: Branch to monitor\n- **interval**: Polling interval (e.g., \"30s\", \"1m\", \"5m\")\n- **command**: Shell command to execute when new commits are detected (supports pipes, redirects, quotes, etc.)\n- **workdir**: Directory where repositories will be cloned\n- **timeout** (optional): Maximum duration for command execution (e.g., \"5m\", \"30s\"). If not specified, commands run without timeout. Commands exceeding the timeout are killed with SIGKILL.\n\n## Usage\n\n```bash\n# Check version\n./ngenteni --version\n./ngenteni -v\n\n# Use default config.json\n./ngenteni\n\n# Use custom config file\n./ngenteni /path/to/config.json\n\n# Stop gracefully\n# Press Ctrl+C - watchers will stop cleanly after completing current operations\n```\n\n## Environment Variables\n\nWhen a command is executed, the following environment variables are available:\n\n- `REPO_NAME`: Repository name from config\n- `REPO_PATH`: Local path to the cloned repository\n- `REPO_URL`: Git repository URL\n- `REPO_BRANCH`: Branch being monitored\n- `OLD_COMMIT`: Previous commit SHA\n- `NEW_COMMIT`: New commit SHA\n\n### Command Syntax\n\nCommands are executed through a shell (`sh -c`), which means you can use:\n- Shell pipes: `command1 | command2`\n- Redirects: `command \u003e output.txt`\n- Logical operators: `command1 \u0026\u0026 command2 || command3`\n- Environment variables: `echo $REPO_NAME`\n- Quotes and complex strings\n\n**Inline commands:**\n```json\n{\n  \"command\": \"echo 'New commit in' $REPO_NAME '!' \u0026\u0026 /opt/notify.sh\"\n}\n```\n\n**Script files:**\n```json\n{\n  \"command\": \"/path/to/script.sh\"\n}\n```\n\n### Example Command Script\n\n```bash\n#!/bin/bash\n# deploy.sh\n\necho \"Repository: $REPO_NAME\"\necho \"New commit: $NEW_COMMIT\"\necho \"Path: $REPO_PATH\"\n\n# Example: Deploy application\ncd \"$REPO_PATH\"\n./deploy.sh\n```\n\nMake it executable and reference it in config:\n\n```json\n{\n  \"command\": \"/path/to/deploy.sh\"\n}\n```\n\n## Example Use Cases\n\n### Continuous Deployment\n\n```json\n{\n  \"name\": \"prod-app\",\n  \"url\": \"https://github.com/company/app.git\",\n  \"branch\": \"main\",\n  \"interval\": \"1m\",\n  \"command\": \"/opt/scripts/deploy.sh\",\n  \"workdir\": \"./repos\"\n}\n```\n\n### Notification on Changes\n\n```json\n{\n  \"name\": \"watched-repo\",\n  \"url\": \"https://github.com/user/repo.git\",\n  \"branch\": \"develop\",\n  \"interval\": \"5m\",\n  \"command\": \"curl -X POST https://hooks.slack.com/... -d '{\\\"text\\\": \\\"New commit in watched-repo\\\"}'\",\n  \"workdir\": \"./repos\"\n}\n```\n\n### Run Tests\n\n```json\n{\n  \"name\": \"test-project\",\n  \"url\": \"https://github.com/team/project.git\",\n  \"branch\": \"main\",\n  \"interval\": \"2m\",\n  \"command\": \"make test\",\n  \"workdir\": \"./repos\"\n}\n```\n\n## How It Works\n\n1. **Initialization**: Clones repositories if they don't exist locally\n2. **Monitoring**: Periodically runs `git fetch` to check for new commits on the remote branch\n3. **Detection**: Compares remote branch commit SHA with the last known commit\n4. **Synchronization**: Updates local working directory to match remote when new commits are detected\n5. **Execution**: Runs the configured command with the latest files from the repository\n6. **Repeat**: Continues monitoring at the specified interval\n\n**Note**: When new commits are detected, ngenteni automatically syncs the local working directory (using `git reset --hard origin/\u003cbranch\u003e`) before running your command. This ensures your command always works with the latest files.\n\n## Requirements\n\n- Go 1.16 or higher\n- Git installed and available in PATH\n- Network access to remote repositories\n\n## Tips\n\n- Use SSH URLs with SSH keys for private repositories\n- Set appropriate intervals to avoid rate limiting\n- Test your commands before deploying\n- Use absolute paths for commands and scripts\n- Check logs for any errors or issues\n\n## Development\n\n### Running Tests\n\n```bash\n# Quick test run\ngo test ./...\n\n# Run a specific test function\ngo test -v -run TestLoadConfig\n\n# Coverage summary\ngo test -cover ./...\n\n# Visual HTML coverage report\ngo test -coverprofile=coverage.out ./...\ngo tool cover -html=coverage.out -o coverage.html\n```\n\n### Building Locally\n\n```bash\ngo build -o ngenteni main.go\n```\n\n### Creating a Release\n\nThis project uses [GoReleaser](https://goreleaser.com/) for releases. For detailed release instructions, see [docs/releasing.md](docs/releasing.md).\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgedex%2Fngenteni","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgedex%2Fngenteni","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgedex%2Fngenteni/lists"}