Skip to main content

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.

PyPI version Python License: MIT

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:

  1. Go to Bitbucket Settings → App passwords
  2. Create a new app password with repository read/write permissions
  3. Update ~/.ngen-gitops/config.json with 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 username
  • BITBUCKET_APP_PASSWORD: Bitbucket app password
  • BITBUCKET_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:

  1. Check config file exists: ~/.ngen-gitops/config.json
  2. Verify credentials are set correctly
  3. Or set environment variables: BITBUCKET_USER and BITBUCKET_APP_PASSWORD

Branch Not Found

Problem: Source branch 'xyz' not found

Solution:

  1. Verify branch name is correct (case-sensitive)
  2. Check branch exists in Bitbucket repository
  3. Use git branch -a to list all branches

Image Update Fails

Problem: File 'k8s/deployment.yaml' not found

Solution:

  1. Verify YAML path is correct relative to repository root
  2. Check file exists in the specified branch
  3. 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ngen_gitops-0.1.1.tar.gz (16.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ngen_gitops-0.1.1-py3-none-any.whl (15.2 kB view details)

Uploaded Python 3

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

Hashes for ngen_gitops-0.1.1.tar.gz
Algorithm Hash digest
SHA256 cebc39afd991816c2ec166b9f6144e0ee7b3a344346235f7e59286d10f481599
MD5 bba9985d14a84608eecc164476f93c70
BLAKE2b-256 ad8e8fe974a9deaa6664153bd481b30b980ae187614bcf01f49840e488cb3be0

See more details on using hashes here.

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

Hashes for ngen_gitops-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e16f5a8b858b495604e21fcb6e72cd1ef67f3381892d95879051e5ffcf049082
MD5 d1f26a2979bc4a9f48bc2992aa732a93
BLAKE2b-256 14df5362e4b9b399fd3f602d0ea63df3418744d69dd2fc7ea67b55cb2a1fe952

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page