# GitHub and GitLab Sync

Source: https://docs.ops0.com/docs/iac/github-sync

Connect your IaC projects to GitHub or GitLab repositories. Push code, create branches, open pull requests, and maintain a complete version history of every infrastructure change.

## Why Version Control Your IaC?

- **Audit Trail**: Every change is a commit. Know who changed what and when, with the full diff.

- **Code Review**: Use pull requests to require peer review before infrastructure changes merge.

- **Rollback**: Git history is your rollback mechanism. Revert to any prior state.

- **CI/CD Integration**: Trigger pipelines from merged PRs. Run additional validation, policy checks, or automated deployments.

---

## Supported Providers

| Provider | Push Code | Sync Back | Create Branch | Open PR/MR | PR Status |
|----------|-----------|-----------|---------------|------------|-----------|
| **GitHub** | ✅ | ✅ | ✅ | ✅ (Pull Request) | ✅ |
| **GitLab** | ✅ | ✅ | ✅ | ✅ (Merge Request) | ✅ |

---

## Prerequisites

- A GitHub integration or GitLab integration configured at **Settings → Integrations → GitHub** (or GitLab)
- The integration must have write access to the target repository

---

## Connecting a Repository

### Click the GitHub (or GitLab) Button
In the IaC editor toolbar, click the **GitHub** or **GitLab** button.

### Select Repository
Choose from your connected repositories. You can also type to filter by name.

### Choose Branch
Select an existing branch or type a new branch name to create one.

### Set Path (Optional)
Specify the subdirectory path where Terraform files should live in the repository — for example `/infrastructure/networking` or `/teams/platform/vpc`. Leave blank to use the repository root. This lets one repository contain multiple ops0 projects in separate directories.

### Save Connection
Click **Connect**. The repository and branch are saved for this project.

---

## Push Actions

After connecting a repository, the Git button in the toolbar gives you these actions:

| Action | Description |
|--------|-------------|
| **Push to GitHub** | Commit all current files and push to the connected branch |
| **Sync from GitHub** | Pull the latest commits from the remote branch into ops0 |
| **Create Pull Request** | Push to a new branch and open a PR/MR for review |
| **View PR on GitHub** | Open the connected pull request in your browser |
| **Check PR Status** | See whether the PR is open, merged, or closed — the GitHub button in the toolbar shows a colored badge: grey (no PR), yellow (open), green (merged), red (closed/rejected) |

---

## Pushing Code

Pushing commits all files in the current project state to the configured branch.

### Click Push
In the toolbar, click **GitHub** → **Push to GitHub**.

### Write a Commit Message
Enter a descriptive message: "Add RDS instance with automated backups" or "Update security group rules for web tier".

### Confirm
Click **Push**. ops0 commits the files and pushes to the remote branch.

Each push creates a single commit containing all files in the project. The commit records which user triggered the push.

---

## Pull Requests and Merge Requests

For team environments, use pull requests instead of pushing directly to your main branch.

### Click Create Pull Request
In the toolbar, click **GitHub** → **Create Pull Request**.

### Set Branch Name
Enter the feature branch name: `feature/add-rds`, `infra/vpc-update`, `fix/security-group-rules`.

### Enter PR Title and Description
Write a clear title and describe what the infrastructure change does, why it's needed, and any cost impact.

### Create
Click **Create PR**. ops0 pushes the code to the new branch and opens a PR in GitHub (or MR in GitLab).

After creation, the PR link appears in the toolbar. Click **View PR on GitHub** to review and merge it.

### Recommended PR Description Template

```markdown
## Summary
Brief description of what infrastructure is being added, changed, or removed.

## Resources Changed
- `aws_db_instance.main` — New: PostgreSQL 15.4 on db.t3.medium
- `aws_security_group.db` — New: Port 5432 from app security group

## Cost Impact
Estimated monthly cost change: +$51.30/month

## Testing
- [ ] Validate passes
- [ ] Plan shows expected resources only
- [ ] No unintended destroy operations
- [ ] Policy checks pass
```

---

## Syncing Back from Git

If changes are made directly in the repository (by a teammate, a CI pipeline, or another tool), pull them back into the ops0 editor:

1. In the toolbar, click **GitHub** → **Sync from GitHub**
2. ops0 fetches the latest commits from the connected branch
3. Files in the editor update to match the remote

**Sync Overwrites Local Changes**

Syncing from GitHub replaces your current editor files with the remote content. If you have unsaved changes in the editor that haven't been pushed, push first or they will be lost.

---

## Handling Conflicts

If remote commits have diverged from the local state, ops0 detects the conflict and presents options:

| Option | Effect |
|--------|--------|
| **Keep Local** | Discard remote changes, push local files as the source of truth |
| **Keep Remote** | Discard local edits, accept the remote version |
| **View Diff** | See a side-by-side comparison before deciding |

For complex conflicts, resolve them in your local Git client, push the resolved code to the branch, then sync back into ops0.

---

## Recommended `.gitignore`

Add this to the root of your repository to avoid committing Terraform runtime files:

```gitignore
# Terraform
**/.terraform/
*.tfstate
*.tfstate.*
crash.log
crash.*.log
*.tfvars
*.tfvars.json
override.tf
override.tf.json
*_override.tf
*_override.tf.json
.terraform.lock.hcl

# Sensitive values — never commit
secrets.auto.tfvars
terraform.auto.tfvars
```

---

## Example: Team Collaboration Workflow

### Scenario

You're adding an RDS database. A teammate is updating security groups in the same project.

### Sync First
Click **GitHub** → **Sync from GitHub** to pull your teammate's latest security group changes.

### Create Feature Branch
Click **GitHub** → **Create Pull Request**. Set branch to `feature/add-rds`.

### Write the Code
Use the AI chat: *"Add an RDS PostgreSQL 15 instance using the existing VPC private subnets"*.

### Push Updates
Click **GitHub** → **Push to GitHub** to commit the generated files to the PR branch.

### Teammate Reviews
Your teammate opens the PR in GitHub, reviews the plan output (add this to the PR description), and approves.

### Merge and Deploy
PR merges to main. In ops0, sync from GitHub and deploy from the updated main branch.

### Commit History After the Workflow

```
main
├── a1b2c3d  Add VPC and subnets (initial)
├── d4e5f6g  Update security group ingress rules (teammate)
└── g7h8i9j  [PR #12] Add RDS PostgreSQL instance
```

---

## GitLab Differences

The GitLab integration works identically to GitHub with these naming differences:

| GitHub | GitLab equivalent |
|--------|-------------------|
| Pull Request | Merge Request |
| Repository | Project |
| Organization | Group |
| `github.com` | `gitlab.com` or self-hosted |

Self-hosted GitLab instances are supported. Configure the base URL in **Settings → Integrations → GitLab**.

---

## GitOps Workflow

For fully automated deployments, combine GitHub sync with ops0 deployments:

1. Developer writes IaC in ops0, pushes a PR
2. Teammate reviews and merges the PR
3. Sync from GitHub in ops0 (or use a workflow trigger)
4. Deploy runs automatically against the merged code

For step-by-step setup, see the [Set Up GitOps Workflow](https://docs.ops0.com/docs/how-to/setup-gitops) guide.

---

## Related

- [Settings: GitHub Integration](https://docs.ops0.com/docs/settings/integrations/github): Connect your GitHub account to ops0.

- [Settings: GitLab Integration](https://docs.ops0.com/docs/settings/integrations/gitlab): Connect your GitLab account or self-hosted instance.

- [Deployments](https://docs.ops0.com/docs/iac/deployments): Plan and apply infrastructure changes after syncing.

- [Set Up GitOps](https://docs.ops0.com/docs/how-to/setup-gitops): End-to-end guide for automated GitOps deployments.
