7.4 KiB
title, tags
| title | tags | |
|---|---|---|
| Git Workflow |
|
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
.gitmessagetemplate (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
- Open the PR with a description that covers what, why, and how to test.
- Link to the related ticket / issue.
- CI must be green (build, lint, tests where wired up).
- At least one reviewer approves.
- Squash-merge into
developmentwith a clean conventional-commit message. - 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
maintriggers thedocker-build-no-cache.ymlworkflow on the backend (anddeploy.ymlon the frontend) — see CI-CD Pipeline. - That workflow builds the image and pushes both
:<version>and:latesttogit.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.jsonversionis the source of truth.- The AI version scripts (
backend/scripts/ai-enhanced.sh,frontend/scripts/ai-enhanced.sh) classify the last commit:feat:→ minorfix:→ patchfeat!:orBREAKING CHANGE:→ majordocs:/chore:/[skip-version]→ skip
auto-version.shapplies the bump, commits, tagsv<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.productionwith public values — if you add a real secret, treat it as leaked and rotate.
[!warning] Never force-push
mainordevelopment. If you absolutely must rewrite history, coordinate with the team and re-tag the affected versions.