Versioning & GitOps
How to version control your agents, track prompt changes, and implement GitOps workflows.
Why Version Control Agents?
Agent .md files are code. Treat them like source code:
- Track changes - See who changed what and when
- Review changes - Code review for prompts before deployment
- Rollback - Revert to previous working version
- Collaboration - Multiple people can work on agents
- Audit trail - Compliance and debugging
- Environment promotion - Dev → Staging → Prod
Git Setup
Initialize Repository
cd /Users/zfab/repos/agentmd
# Initialize git (if not already)
git init
# Add .gitignore
cat > .gitignore << 'EOF'
# Environment files (NEVER commit these)
.env
.env.local
.env.*.local
# Secrets
secrets/
*.key
*.pem
# Output (generated by agents)
output/
# Database
data/
*.db
*.db-journal
# Python
__pycache__/
*.pyc
.venv/
venv/
# OS
.DS_Store
Thumbs.db
EOF
git add .gitignore
git commit -m "Add .gitignore"
Directory Structure
agentmd/
├── .git/
├── .gitignore
├── .env # Gitignored
├── .env.example # Committed (template)
├── workspace/
│ ├── production/ # Production agents
│ │ ├── daily-report.md
│ │ └── log-monitor.md
│ ├── staging/ # Staging agents
│ │ └── new-feature.md
│ └── dev/ # Development agents
│ └── experiment.md
├── output/ # Gitignored
└── data/ # Gitignored
Commit Agent Files
# Add all agent files
git add workspace/
# Commit
git commit -m "Add daily report and log monitor agents"
Best practices:
- Commit .md agent files ✓
- Commit .env.example template ✓
- Never commit .env with secrets ✗
- Never commit output/ generated files ✗
- Never commit data/ database files ✗
Git Diff for Prompts
Track Prompt Changes
Example diff:
diff --git a/workspace/daily-report.md b/workspace/daily-report.md
index abc123..def456 100644
--- a/workspace/daily-report.md
+++ b/workspace/daily-report.md
@@ -5,7 +5,7 @@ model:
name: gpt-4
triggers:
- type: schedule
- cron: "0 9 * * *" # 9 AM daily
+ cron: "0 8 * * *" # 8 AM daily
---
-Generate a summary of yesterday's activities.
+Generate a detailed summary of yesterday's activities, including:
+1. Key metrics
+2. Error count
+3. Recommendations
Review Config Changes
Compare Versions
# Compare current with last commit
git diff HEAD workspace/daily-report.md
# Compare with specific commit
git diff abc123 workspace/daily-report.md
# Compare two branches
git diff main staging -- workspace/daily-report.md
Rollback
Revert to Previous Version
Scenario: Agent started producing bad output after a prompt change.
# View history
git log --oneline workspace/daily-report.md
# Output:
# def456 Update daily report schedule
# abc123 Add error count to report
# 789xyz Initial daily report agent
# Revert to before bad change
git checkout abc123 -- workspace/daily-report.md
# Commit the revert
git commit -m "Revert daily report to working version (abc123)"
Undo Last Commit
# Undo commit but keep changes
git reset --soft HEAD~1
# Undo commit and discard changes (CAREFUL!)
git reset --hard HEAD~1
Revert Specific Change
# Revert a specific commit (creates new commit)
git revert def456
# This creates an inverse commit that undoes def456
View File at Specific Commit
# View without checking out
git show abc123:workspace/daily-report.md
# Save to file for comparison
git show abc123:workspace/daily-report.md > /tmp/old-version.md
diff /tmp/old-version.md workspace/daily-report.md
Pull Request Workflow
Branching Strategy
# Main branches
main # Production
staging # Staging environment
dev # Development
# Feature branches
feature/add-new-agent
feature/improve-daily-report
fix/log-monitor-timeout
Create Feature Branch
# Create and switch to feature branch
git checkout -b feature/add-email-digest
# Create new agent
cat > workspace/staging/email-digest.md << 'EOF'
---
name: email-digest
model:
provider: openai
name: gpt-3.5-turbo
triggers:
- type: schedule
cron: "0 8 * * *"
---
Generate a daily email digest from /workspace/data/emails/.
EOF
# Commit
git add workspace/staging/email-digest.md
git commit -m "Add email digest agent"
Push and Create PR
# Push feature branch
git push origin feature/add-email-digest
# Create PR (using GitHub CLI)
gh pr create \
--title "Add email digest agent" \
--body "New agent to generate daily email digest. Runs at 8 AM daily." \
--base main \
--head feature/add-email-digest
PR Review Checklist
Reviewer checks:
- Agent config is valid (
agentmd validate) - No secrets in frontmatter
- Appropriate
paths.readandpaths.writerestrictions - Schedule frequency is reasonable
-
max_tokensandtimeoutare set - Prompt is clear and concise
- Temperature appropriate for task
- Model choice is cost-effective
- Tested in staging environment
Review command:
# Checkout PR branch
gh pr checkout 123
# Validate agent
agentmd validate workspace/staging/email-digest.md
# Test run
agentmd run email-digest --dry-run
# Review diff
git diff main...feature/add-email-digest
Merge and Deploy
# Merge PR (via GitHub UI or CLI)
gh pr merge 123 --squash
# Pull latest main
git checkout main
git pull
# Deploy to production
# (See deployment section below)
Configuration History
Track Config Changes Over Time
# View all changes to a specific field
git log -p workspace/daily-report.md | grep -A 5 "cron:"
# Output:
# commit def456
# cron: "0 8 * * *"
#
# commit abc123
# cron: "0 9 * * *"
Annotate Lines
# See who last changed each line
git blame workspace/daily-report.md
# Output:
# abc123 (Alice 2026-03-01) ---
# abc123 (Alice 2026-03-01) name: daily-report
# def456 (Bob 2026-03-10) model:
# def456 (Bob 2026-03-10) provider: openai
Compare Configurations Across Environments
# Compare dev vs staging
git diff dev staging -- workspace/daily-report.md
# Compare staging vs production
git diff staging main -- workspace/daily-report.md
GitOps Deployment
Environment Branches
Promotion flow:
Dev branch → Test → Merge to staging branch
Staging branch → Test → Merge to main branch
Main branch → Auto-deploy to production
Automatic Deployment
GitHub Actions (.github/workflows/deploy.yml):
name: Deploy Agents
on:
push:
branches: [main]
paths: ['workspace/**/*.md']
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.13'
- name: Install Agent.md
run: |
pip install -e .
pip install -e ".[all]"
- name: Validate agents
run: |
for agent in workspace/production/*.md; do
agentmd validate "$agent"
done
- name: Deploy to production server
env:
SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
run: |
# Copy agents to production server
scp workspace/production/*.md user@prod-server:/opt/agentmd/workspace/
# Restart agent runtime
ssh user@prod-server 'systemctl restart agentmd'
Manual Deployment
# 1. Validate all agents
for agent in workspace/production/*.md; do
agentmd validate "$agent" || exit 1
done
# 2. Copy to production server
rsync -avz workspace/production/ user@prod-server:/opt/agentmd/workspace/
# 3. Restart runtime on server
ssh user@prod-server 'systemctl restart agentmd'
Blue-Green Deployment
Run two environments side-by-side:
# Blue environment (current production)
/opt/agentmd-blue/
workspace/production/
# Green environment (new version)
/opt/agentmd-green/
workspace/production/
# Switch: Update symlink
ln -sfn /opt/agentmd-green /opt/agentmd-current
# Rollback: Switch back
ln -sfn /opt/agentmd-blue /opt/agentmd-current
Tagging Releases
Create Release Tag
# Tag current version
git tag -a v1.0.0 -m "Release v1.0.0: Add email digest agent"
# Push tag
git push origin v1.0.0
View Releases
Deploy Specific Version
# Checkout specific version
git checkout v1.0.0
# Deploy
rsync -avz workspace/production/ user@prod-server:/opt/agentmd/workspace/
Collaboration Workflow
Multiple Contributors
Workflow:
1. Create feature branch from main
2. Make changes
3. Create PR
4. Review by team member
5. Merge to staging for testing
6. Merge to main for production
Example:
# Alice: Add new agent
git checkout -b feature/alice-new-agent
# ... work ...
git push origin feature/alice-new-agent
gh pr create
# Bob: Review
gh pr checkout 123
agentmd validate workspace/staging/new-agent.md
gh pr review 123 --approve
# Alice: Merge to staging
gh pr merge 123 --squash
Prevent Conflicts
Use separate files:
Or use feature branches:
# Alice works on feature/alice-agent
# Bob works on feature/bob-agent
# No conflicts because different branches
Audit Trail
Track All Changes
Who Changed What When
# See all commits by author
git log --author="Alice" workspace/
# See changes in date range
git log --since="2026-03-01" --until="2026-03-10" workspace/
Generate Changelog
# Changes since last tag
git log v1.0.0..HEAD --oneline workspace/
# Detailed changelog
git log v1.0.0..HEAD --pretty=format:"- %s (%an, %ar)" workspace/
Example output:
- Add email digest agent (Alice, 2 days ago)
- Update daily report schedule (Bob, 1 week ago)
- Fix log monitor timeout (Charlie, 2 weeks ago)
Best Practices
Commit Messages
Good:
Add email digest agent
Creates daily email digest at 8 AM.
Reads from /workspace/data/emails/.
Outputs to /output/digest.html.
Bad:
Conventional Commits:
feat: add email digest agent
fix: resolve log monitor timeout
docs: update daily report description
refactor: simplify prompt for better performance
Branching Convention
main # Production (protected)
staging # Staging (protected)
dev # Development
feature/<name> # New features
fix/<name> # Bug fixes
refactor/<name> # Refactoring
docs/<name> # Documentation
PR Description Template
## Description
Brief description of changes.
## Agent Changes
- Added: `email-digest.md`
- Modified: `daily-report.md` (changed schedule from 9 AM to 8 AM)
## Testing
- [ ] Validated with `agentmd validate`
- [ ] Tested in dev environment
- [ ] Tested in staging environment
- [ ] Reviewed token usage
- [ ] Reviewed permissions
## Deployment Plan
Deploy to production after 2 days in staging with no issues.
Protected Branches
GitHub settings:
Branch: main
- Require pull request before merging
- Require approvals: 1
- Require status checks to pass: ✓
- validate-agents
- test-run
- Include administrators: ✓
Recovery Scenarios
Accidentally Committed Secret
# Remove secret from file
vim workspace/daily-report.md # Remove secret
# Amend last commit
git add workspace/daily-report.md
git commit --amend
# Force push (if already pushed - CAREFUL!)
git push --force origin feature/daily-report
# Better: Use git-secrets or pre-commit hooks to prevent
Lost Work
# View reflog (all commits, even deleted)
git reflog
# Output:
# abc123 HEAD@{0}: reset: moving to HEAD~1
# def456 HEAD@{1}: commit: Add new agent
# Recover deleted commit
git checkout def456
Diverged Branches
# Pull with rebase to keep linear history
git pull --rebase origin main
# Or merge
git pull origin main
Monitoring and Alerts
Track Deployment Success
Alert on Failed Validation
# Pre-commit hook (.git/hooks/pre-commit)
#!/bin/bash
for agent in workspace/**/*.md; do
agentmd validate "$agent" || exit 1
done