Files
nick-doc/07 - Development/Git Workflow.md
2026-05-23 20:35:34 +03:30

7.4 KiB

title, tags
title tags
Git Workflow
development

Git Workflow

How code moves from a developer's laptop to production.


1. Repositories & branches

Both repos are hosted on the self-hosted Gitea instance at git.manko.yoga (SSH on port 222, HTTPS on 443).

Repo Path Branches
Backend ssh://git@git.manko.yoga:222/nick/backend.git main, development, feature/*, fix/*
Frontend ssh://git@git.manko.yoga:222/nick/frontend.git main, development, feature/*, fix/*

Branch roles

Branch Role Auto-deploy
main (or master) Production. Always deployable. Yes — Gitea Actions builds + pushes :latest, Watchtower then pulls it. See CI-CD Pipeline and Deployment.
development Active dev. Integration branch where features land before promotion. Yes — builds + pushes :dev tag (not consumed by prod Watchtower).
feature/<short-slug> One change in flight. Branched from development. No
fix/<short-slug> A bug fix. Branched from development (or main for a hotfix). No
hotfix/<slug> Urgent production fix branched from main. No until merged
main         ─●────────●───────────────●───────►  (prod, tagged v2.6.x)
                                                        ▲ release merge
development  ─●────●────●───●───●────●────●────●──►     │
                  ▲    ▲    ▲    ▲    ▲                 │
                  │    │    │    │    │                 │
feature/*       branches off development                │
hotfix/*    ─────────────────────────────●──────────────┘

2. Day-to-day developer flow

# 1. Sync development
git checkout development
git pull --rebase

# 2. Create a branch
git checkout -b feature/add-seller-payouts

# 3. Hack
# ...

# 4. Verify locally
npm run lint && npm run typecheck && npm run test
# or for frontend
yarn lint && yarn test

# 5. Commit (Conventional Commits — see Coding Standards)
git commit -m "feat(payment): add seller payout history view"

# 6. Push & open PR
git push -u origin feature/add-seller-payouts

Open the PR in Gitea against development. CI will run on the PR if you have workflows enabled.

[!tip] Use the .gitmessage template (git config commit.template .gitmessage) — it pre-fills the conventional-commit format with hints.


3. Commit message convention

Enforced on the frontend by frontend/.commitlintrc.json (and followed by convention on backend). See Coding Standards#commit-conventions for the full rules and examples.

Quick reference:

type(scope): subject

feat: add user authentication
fix(payment): handle missing tx hash
docs: clarify env vars table
chore: bump dependencies
feat!: redesign API endpoints      # breaking change

Append [skip-version] to skip the auto-version bump when releasing.


4. PR review process

  1. Open the PR with a description that covers what, why, and how to test.
  2. Link to the related ticket / issue.
  3. CI must be green (build, lint, tests where wired up).
  4. At least one reviewer approves.
  5. Squash-merge into development with a clean conventional-commit message.
  6. Delete the source branch.

Reviewers check against Coding Standards#pr-review-checklist.

[!warning] Do not force-push to a PR branch after review starts — it invalidates review history. Use additional commits and let the squash-merge tidy up.


5. Releasing to production

The release path is development → main → registry → production.

# On a clean development that's ready to ship:
git checkout development
git pull --rebase

# Run AI-assisted version bump (chooses major/minor/patch from commit messages)
npm run smart-release
# This: bumps package.json, commits "chore: bump version to vX.Y.Z",
# creates a `vX.Y.Z` tag, and pushes commits + tags.

# Promote to main
git checkout main
git pull --rebase
git merge --ff-only development      # fast-forward only — no merge commit
git push

What happens next:

  • Pushing to main triggers the docker-build-no-cache.yml workflow on the backend (and deploy.yml on the frontend) — see CI-CD Pipeline.
  • That workflow builds the image and pushes both :<version> and :latest to git.manko.yoga/manawenuz/escrow-backend.
  • Watchtower on the production host (see Deployment) polls the registry every interval, detects the new :latest, and rolls the production container.

Manual builds

If you want to push a specific version without going through main, use:

# Backend
npm run release:patch                 # commits + tags + pushes; CI handles the rest
./scripts/build-and-push.sh           # build locally and push dev tag

# Frontend
./scripts/deploy.sh                   # local build + push :latest

See Scripts for details.


6. Versioning

Semantic versioning, automated where possible.

  • package.json version is the source of truth.
  • The AI version scripts (backend/scripts/ai-enhanced.sh, frontend/scripts/ai-enhanced.sh) classify the last commit:
    • feat: → minor
    • fix: → patch
    • feat!: or BREAKING CHANGE: → major
    • docs:/chore:/[skip-version] → skip
  • auto-version.sh applies the bump, commits, tags v<version>, and (with the npm wrappers) pushes.

Confidence levels (high/medium/low/very-low) gate the action — low confidence asks for a manual decision rather than auto-applying.

The CI workflows tag built images with both the package.json version and the moving tag (:latest for main, :dev for development).


7. Hotfix flow

# Branch from main
git checkout main && git pull --rebase
git checkout -b hotfix/critical-payment-bug

# Fix, test, commit
git commit -m "fix(payment): correct rounding on payout amount"

# Push + PR into main
git push -u origin hotfix/critical-payment-bug
# (open PR targeted at main; merge after review)

# After merge, port the fix back to development:
git checkout development && git pull --rebase
git merge --no-ff main
git push

Bump the patch version on main before merging so the new image gets a real tag, not just :latest.


8. SSH access on port 222

Gitea SSH listens on 222, not 22, so the URL is always ssh://git@git.manko.yoga:222/.... Add this once to ~/.ssh/config:

Host git.manko.yoga
  HostName git.manko.yoga
  Port 222
  User git
  IdentityFile ~/.ssh/id_ed25519

Then git clone git@git.manko.yoga:nick/backend.git "just works" without the explicit :222.

Container registry uses standard ports — git.manko.yoga/manawenuz/escrow-backend:latest over HTTPS — authenticated by a personal access token (GITEATOKEN secret in CI).


9. Rules of thumb

[!tip] Keep PRs small. Anything > 500 LOC of net change is a candidate for splitting.

[!warning] Never commit .env* files containing real secrets. The repos do already have committed .env.development / .env.production with public values — if you add a real secret, treat it as leaked and rotate.

[!warning] Never force-push main or development. If you absolutely must rewrite history, coordinate with the team and re-tag the affected versions.