# Git workflow and deployment

A push to main starts the pipeline, which derives the version from the commit messages, rolls out dev automatically and releases production through a manual job; an earlier state can be restored the same way.

> Source: https://www.application-platform.com/en/docs/git-workflow/

## Branches and merge requests

The trigger for a deployment is `main`; whether you push directly or merge feature branches through merge requests is your team's decision. Feature branches run through the pipeline with dynamic build versions, but without a version commit or deployment.

```bash
git checkout main
git pull
git add .
git commit -m "feat: persist shopping cart"
git push
```

Pull the current state of `main` before you push, because the pipeline creates version commits there itself. The pre-commit hook `ap git pre-commit check` from the setup app and `ap platform projects clone` blocks commits to `.gitlab-ci.yml` and `env/*.generated.env`; `ap git auto-commit` handles staging, commit and push in one step.

## The pipeline on main

```mermaid
flowchart LR
  test["test"] --> version["update-version"]
  version --> build["build"]
  build -->|"automatic"| publish["publish: dev"]
  publish -->|"manual job"| release["release: prod"]
```

`test` runs tests and checks, `update-version` derives the next version following Conventional Commits (`feat:` raises the minor version, `fix:` the patch version), and `build` produces the Docker image or the app build with that version. `publish` records the state in `configurations/dev/versions.yaml` of `gitops-configuration`, after which the dev server pulls the version; for apps, `publish` means TestFlight and the internal track on Google Play. `release` is the manual job for production or the store submission. Every job has a log in GitLab under **CI/CD → Pipelines**, the first place to look when a pipeline turns red.

## Releasing production

Production receives exactly the build that already runs on dev. In GitLab, open the pipeline of the `main` state you want to roll out under **CI/CD → Pipelines** and start the production job via the play button; the pipeline writes the version into `configurations/prod/versions.yaml`, and the prod server pulls it. There is no further confirmation step between release and going live, so verify the change on dev beforehand.

You maintain your own environment variables for dev or prod in `gitops-configuration/configurations/<env>/custom.yaml`; a commit to `main` in that repository rolls the change out without building a new image. [Environment variables]({{< relref "environment-setup" >}}) describes the files.

## Returning to an earlier state

Because every pipeline keeps its build, a rollback is the same click as a release: open the pipeline of the last working `main` state and start its production job again. Which version runs where is recorded in the `versions.yaml` of each environment; Sentry links errors to the same release version once a Sentry account is connected under **Connections**. How to keep an eye on errors and servers after a release is covered in [Operations]({{< relref "operations" >}}).

