GitOps CLI and web server for Bitbucket operations
Project description
ngen-gitops
GitOps CLI and web server for Bitbucket operations. Automate branch creation, YAML image updates, pull request creation, and merging via command-line interface or REST API.
Features
- 🌿 Branch Management: Create branches from source branches
- 🖼️ Image Updates: Update container images in Kubernetes YAML files
- 🔄 Pull Requests: Create and merge pull requests automatically
- 🌐 Web API: REST API server with FastAPI for integration
- 🔐 Secure: Uses Bitbucket app passwords for authentication
- 📦 Easy Configuration: Simple JSON config file
- 🚀 PyPI Package: Install with pip
Installation
pip install ngen-gitops
Quick Start
1. Configuration
On first run, ngen-gitops creates a config file at ~/.ngen-gitops/config.json:
{
"bitbucket": {
"username": "",
"app_password": "",
"organization": "loyaltoid"
},
"server": {
"host": "0.0.0.0",
"port": 8080
}
}
Update the config with your credentials:
- Go to Bitbucket Settings → App passwords
- Create a new app password with repository read/write permissions
- Update
~/.ngen-gitops/config.jsonwith your username and app password
Or use environment variables:
export BITBUCKET_USER="your-username"
export BITBUCKET_APP_PASSWORD="your-app-password"
export BITBUCKET_ORG="your-organization"
2. Verify Configuration
ngen-gitops config
Usage
CLI Commands
Create Branch
Create a new branch from a source branch:
ngen-gitops create-branch <repo> <src_branch> <dest_branch>
Example:
ngen-gitops create-branch my-app main feature/new-feature
Output:
🔍 Creating branch 'feature/new-feature' from 'main' in repository 'my-app'...
✅ Source branch 'main' validated (commit: abc1234)
✅ Branch 'feature/new-feature' created successfully from 'main'
✅ Branch 'feature/new-feature' created successfully
Branch URL: https://bitbucket.org/org/my-app/branch/feature/new-feature
Update Image in YAML
Update container image in Kubernetes YAML file:
ngen-gitops set-image-yaml <repo> <branch> <yaml_path> <image> [--dry-run]
Example:
ngen-gitops set-image-yaml my-app develop k8s/deployment.yaml myregistry/myapp:v1.2.3
Output:
🔍 Cloning repository my-app (branch: develop)...
✅ Repository cloned
Current image(s): myregistry/myapp:v1.2.0
New image: myregistry/myapp:v1.2.3
✅ Updated image in YAML file
✅ Changes committed
✅ Changes pushed to develop
✅ Image updated to myregistry/myapp:v1.2.3 and pushed to develop
[develop abc1234] chore: update image to myregistry/myapp:v1.2.3
Dry-run mode (don't push changes):
ngen-gitops set-image-yaml my-app develop k8s/deployment.yaml myapp:v1.0.0 --dry-run
Create Pull Request
Create a pull request from source to destination branch:
ngen-gitops pull-request <repo> <src_branch> <dest_branch> [--delete-after-merge]
Example:
ngen-gitops pull-request my-app feature/new-feature develop --delete-after-merge
Output:
🔍 Creating pull request from 'feature/new-feature' to 'develop' in repository 'my-app'...
⚠️ Source branch 'feature/new-feature' will be deleted after merge
✅ Source branch 'feature/new-feature' validated
✅ Destination branch 'develop' validated
✅ Pull request created successfully
PR #42
URL: https://bitbucket.org/org/my-app/pull-requests/42
✅ Pull request #42 created successfully
Pull Request URL: https://bitbucket.org/org/my-app/pull-requests/42
Merge Pull Request
Merge an existing pull request:
ngen-gitops merge <pr_url> [--delete-after-merge]
Example:
ngen-gitops merge https://bitbucket.org/org/my-app/pull-requests/42
Output:
🔍 Merging pull request #42 in repository 'my-app'...
✅ Pull request validated
Source branch: feature/new-feature
Destination branch: develop
State: OPEN
✅ Pull request #42 merged successfully
Merge commit: abc1234
✅ Pull request #42 merged successfully
Merge commit: abc1234
Start Web Server
Start the REST API server:
ngen-gitops server [--host HOST] [--port PORT]
Example:
ngen-gitops server --port 8080
Output:
🚀 Starting ngen-gitops server...
Host: 0.0.0.0
Port: 8080
Endpoints:
- POST /v1/gitops/create-branch
- POST /v1/gitops/set-image-yaml
- POST /v1/gitops/pull-request
- POST /v1/gitops/merge
INFO: Started server process [12345]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit)
JSON Output
All commands support --json flag for machine-readable output:
ngen-gitops create-branch my-app main develop --json
Output:
{
"success": true,
"repository": "my-app",
"source_branch": "main",
"destination_branch": "develop",
"message": "Branch 'develop' created successfully",
"branch_url": "https://bitbucket.org/org/my-app/branch/develop"
}
REST API
Starting the Server
ngen-gitops server --port 8080
API Endpoints
1. Create Branch
Endpoint: POST /v1/gitops/create-branch
Request:
{
"repo": "my-app",
"src_branch": "main",
"dest_branch": "feature/new-feature"
}
Response:
{
"success": true,
"repository": "my-app",
"source_branch": "main",
"destination_branch": "feature/new-feature",
"message": "Branch 'feature/new-feature' created successfully",
"branch_url": "https://bitbucket.org/org/my-app/branch/feature/new-feature"
}
cURL Example:
curl -X POST http://localhost:8080/v1/gitops/create-branch \
-H "Content-Type: application/json" \
-d '{
"repo": "my-app",
"src_branch": "main",
"dest_branch": "feature/new-feature"
}'
2. Update Image in YAML
Endpoint: POST /v1/gitops/set-image-yaml
Request:
{
"repo": "my-app",
"refs": "develop",
"yaml_path": "k8s/deployment.yaml",
"image": "myregistry/myapp:v1.2.3",
"dry_run": false
}
Response:
{
"success": true,
"repository": "my-app",
"branch": "develop",
"yaml_path": "k8s/deployment.yaml",
"image": "myregistry/myapp:v1.2.3",
"message": "Image updated to myregistry/myapp:v1.2.3 and pushed to develop",
"commit": "[develop abc1234] chore: update image to myregistry/myapp:v1.2.3"
}
cURL Example:
curl -X POST http://localhost:8080/v1/gitops/set-image-yaml \
-H "Content-Type: application/json" \
-d '{
"repo": "my-app",
"refs": "develop",
"yaml_path": "k8s/deployment.yaml",
"image": "myregistry/myapp:v1.2.3",
"dry_run": false
}'
3. Create Pull Request
Endpoint: POST /v1/gitops/pull-request
Request:
{
"repo": "my-app",
"src_branch": "feature/new-feature",
"dest_branch": "develop",
"delete_after_merge": false
}
Response:
{
"success": true,
"repository": "my-app",
"source": "feature/new-feature",
"destination": "develop",
"delete_after_merge": false,
"pr_id": 42,
"pr_url": "https://bitbucket.org/org/my-app/pull-requests/42",
"message": "Pull request #42 created successfully"
}
cURL Example:
curl -X POST http://localhost:8080/v1/gitops/pull-request \
-H "Content-Type: application/json" \
-d '{
"repo": "my-app",
"src_branch": "feature/new-feature",
"dest_branch": "develop",
"delete_after_merge": false
}'
4. Merge Pull Request
Endpoint: POST /v1/gitops/merge
Request:
{
"pr_url": "https://bitbucket.org/org/my-app/pull-requests/42",
"delete_after_merge": false
}
Response:
{
"success": true,
"pr_url": "https://bitbucket.org/org/my-app/pull-requests/42",
"repository": "my-app",
"pr_id": "42",
"source": "feature/new-feature",
"destination": "develop",
"message": "Pull request #42 merged successfully",
"merge_commit": "abc1234",
"delete_after_merge": false
}
cURL Example:
curl -X POST http://localhost:8080/v1/gitops/merge \
-H "Content-Type: application/json" \
-d '{
"pr_url": "https://bitbucket.org/org/my-app/pull-requests/42",
"delete_after_merge": false
}'
API Documentation
When the server is running, visit:
- Swagger UI:
http://localhost:8080/docs - ReDoc:
http://localhost:8080/redoc
Use Cases
CI/CD Integration
Update image after Docker build:
# Build Docker image
docker build -t myregistry/myapp:${VERSION} .
docker push myregistry/myapp:${VERSION}
# Update Kubernetes deployment
ngen-gitops set-image-yaml my-app develop k8s/deployment.yaml myregistry/myapp:${VERSION}
Automated PR workflow:
# Create feature branch
ngen-gitops create-branch my-app develop feature/auto-update-${VERSION}
# Update image in feature branch
ngen-gitops set-image-yaml my-app feature/auto-update-${VERSION} k8s/deployment.yaml myregistry/myapp:${VERSION}
# Create pull request
PR_URL=$(ngen-gitops pull-request my-app feature/auto-update-${VERSION} develop --delete-after-merge --json | jq -r '.pr_url')
# Auto-merge (optional)
ngen-gitops merge $PR_URL
REST API Integration
Python example:
import requests
# Create branch
response = requests.post('http://localhost:8080/v1/gitops/create-branch', json={
'repo': 'my-app',
'src_branch': 'main',
'dest_branch': 'feature/new-feature'
})
print(response.json())
# Update image
response = requests.post('http://localhost:8080/v1/gitops/set-image-yaml', json={
'repo': 'my-app',
'refs': 'develop',
'yaml_path': 'k8s/deployment.yaml',
'image': 'myapp:v1.0.0',
'dry_run': False
})
print(response.json())
Configuration
Config File Location
~/.ngen-gitops/config.json
Config Structure
{
"bitbucket": {
"username": "your-bitbucket-username",
"app_password": "your-app-password",
"organization": "your-org-name"
},
"server": {
"host": "0.0.0.0",
"port": 8080
}
}
Environment Variables
Override config with environment variables:
BITBUCKET_USER: Bitbucket usernameBITBUCKET_APP_PASSWORD: Bitbucket app passwordBITBUCKET_ORG: Bitbucket organization
Development
Build from Source
# Clone repository
git clone https://github.com/mamatnurahmat/ngen-gitops.git
cd ngen-gitops
# Install in development mode
pip install -e .
# Run commands
ngen-gitops --help
Build Package
# Install build tools
pip install build twine
# Build package
python -m build
# Check distribution
twine check dist/*
Publish to PyPI
# Publish to TestPyPI first
twine upload --repository testpypi dist/*
# Test installation
pip install --index-url https://test.pypi.org/simple/ ngen-gitops
# Publish to PyPI
twine upload dist/*
Troubleshooting
Authentication Errors
Problem: Bitbucket credentials not configured
Solution:
- Check config file exists:
~/.ngen-gitops/config.json - Verify credentials are set correctly
- Or set environment variables:
BITBUCKET_USERandBITBUCKET_APP_PASSWORD
Branch Not Found
Problem: Source branch 'xyz' not found
Solution:
- Verify branch name is correct (case-sensitive)
- Check branch exists in Bitbucket repository
- Use
git branch -ato list all branches
Image Update Fails
Problem: File 'k8s/deployment.yaml' not found
Solution:
- Verify YAML path is correct relative to repository root
- Check file exists in the specified branch
- Ensure YAML file contains
image:field
License
MIT License - see LICENSE file for details
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Author
ngen-gitops contributors
Related Projects
- ngen-j - Jenkins API management CLI
Links
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ngen_gitops-0.1.1.tar.gz.
File metadata
- Download URL: ngen_gitops-0.1.1.tar.gz
- Upload date:
- Size: 16.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cebc39afd991816c2ec166b9f6144e0ee7b3a344346235f7e59286d10f481599
|
|
| MD5 |
bba9985d14a84608eecc164476f93c70
|
|
| BLAKE2b-256 |
ad8e8fe974a9deaa6664153bd481b30b980ae187614bcf01f49840e488cb3be0
|
File details
Details for the file ngen_gitops-0.1.1-py3-none-any.whl.
File metadata
- Download URL: ngen_gitops-0.1.1-py3-none-any.whl
- Upload date:
- Size: 15.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e16f5a8b858b495604e21fcb6e72cd1ef67f3381892d95879051e5ffcf049082
|
|
| MD5 |
d1f26a2979bc4a9f48bc2992aa732a93
|
|
| BLAKE2b-256 |
14df5362e4b9b399fd3f602d0ea63df3418744d69dd2fc7ea67b55cb2a1fe952
|