forked from sagnik/Project_Velocity
#3 Self-approved and unit tests passed with flying colors. Co-authored-by: Sagnik <sagnik7896@gmail.com> Reviewed-on: sagnik/Project_Velocity#5
458 lines
16 KiB
Markdown
458 lines
16 KiB
Markdown
# Project Velocity — Gitea Feature Contribution Guide
|
|
|
|
**Version:** 1.1
|
|
**Last Updated:** 2026-03-07
|
|
**Upstream Repository (Sagnik's):** `https://git.desineuron.in/sagnik/Project_Velocity`
|
|
**Your Fork:** `https://git.desineuron.in/<YOUR_USERNAME>/Project_Velocity`
|
|
|
|
> This document is the **canonical guide** for every team member contributing to Project Velocity.
|
|
> The team uses a **Fork-based workflow**: each contributor has their own fork of Sagnik's repository. All features are developed in your fork and merged into the upstream via Pull Requests.
|
|
> It covers the full lifecycle: Issue → Branch → Commit → Push → Pull Request — both via the **CLI** and via **Antigravity Source Control UI**.
|
|
|
|
### How the Fork Model Works
|
|
|
|
```text
|
|
[upstream] sagnik/Project_Velocity ← the source of truth
|
|
↑ Pull Requests
|
|
[your fork] <you>/Project_Velocity ← where you develop
|
|
↑ git push
|
|
[local] /your/machine/Project_Velocity
|
|
```
|
|
|
|
- `upstream` = Sagnik's repo — you **pull** from here to stay in sync.
|
|
- `origin` = Your fork — you **push** your branches here.
|
|
- PRs go **from your fork → upstream**.
|
|
|
|
---
|
|
|
|
## Table of Contents
|
|
|
|
1. [Naming Conventions](#naming-conventions)
|
|
2. [One-Time Setup — Fork & Remotes](#one-time-setup--fork--remotes)
|
|
3. [Step 0 — Pre-flight: Populate `.gitignore` & `.gitkeep`](#step-0--pre-flight)
|
|
4. [Step 1 — Create a Gitea Issue](#step-1--create-a-gitea-issue)
|
|
5. [Step 2 — Sync with Upstream Before Branching](#step-2--sync-with-upstream-before-branching)
|
|
6. [Step 3 — Create a Feature Branch](#step-3--create-a-feature-branch)
|
|
7. [Step 4 — Make Your Changes & Commit](#step-4--make-your-changes--commit)
|
|
8. [Step 5 — Push the Branch to Your Fork](#step-5--push-the-branch-to-your-fork)
|
|
9. [Step 6 — Create a Pull Request (Fork → Upstream)](#step-6--create-a-pull-request-fork--upstream)
|
|
10. [Quick Reference — CLI Cheat Sheet](#quick-reference--cli-cheat-sheet)
|
|
|
|
---
|
|
|
|
## Naming Conventions
|
|
|
|
Consistent naming keeps the repository clean and makes history easy to read.
|
|
|
|
| Type | Format | Example |
|
|
|------|--------|---------|
|
|
| **Issue Title** | `feat : <Short description>` | `feat : Build the native SwiftUI app shell` |
|
|
| **Branch Name** | `feat/#<issue-number>` | `feat/#12` |
|
|
| **Commit Message** | `feat(scope): <what changed>` or `fix(scope): <what was fixed>` | `feat(ios): add Dashboard, Oracle and Sentinel tab views` |
|
|
|
|
> Use `fix`, `chore`, `docs`, `refactor`, or `test` instead of `feat` where appropriate.
|
|
|
|
---
|
|
|
|
## One-Time Setup — Fork & Remotes
|
|
|
|
Do this **once** when you first clone your fork onto a new machine. You only need to do this once per machine.
|
|
|
|
### 1. Clone your fork
|
|
|
|
```bash
|
|
git clone https://git.desineuron.in/<YOUR_USERNAME>/Project_Velocity.git
|
|
cd Project_Velocity
|
|
```
|
|
|
|
### 2. Add the upstream remote (Sagnik's repo)
|
|
|
|
```bash
|
|
git remote add upstream https://git.desineuron.in/sagnik/Project_Velocity.git
|
|
```
|
|
|
|
### 3. Verify your remotes
|
|
|
|
```bash
|
|
git remote -v
|
|
```
|
|
|
|
You should see **two** remotes:
|
|
|
|
```text
|
|
origin https://git.desineuron.in/<YOUR_USERNAME>/Project_Velocity.git (fetch)
|
|
origin https://git.desineuron.in/<YOUR_USERNAME>/Project_Velocity.git (push)
|
|
upstream https://git.desineuron.in/sagnik/Project_Velocity.git (fetch)
|
|
upstream https://git.desineuron.in/sagnik/Project_Velocity.git (push)
|
|
```
|
|
|
|
> ⚠️ If you only see `origin`, you haven't added `upstream` yet. Run step 2 above.
|
|
|
|
### Via Antigravity Source Control UI
|
|
|
|
Antigravity does not have a direct UI button to add a new remote. Do this once via the terminal:
|
|
1. Open a terminal inside Antigravity (`Ctrl + `` ` `` ` `).
|
|
2. Run: `git remote add upstream https://git.desineuron.in/sagnik/Project_Velocity.git`
|
|
3. The upstream remote will now appear in the **Graph** section of Source Control.
|
|
|
|
---
|
|
|
|
## Step 0 — Pre-flight
|
|
|
|
Before pushing anything, ensure these files are properly configured at the **root of the repository**.
|
|
|
|
### `.gitignore`
|
|
A root `.gitignore` already exists at the repository root. It covers:
|
|
- **macOS** system files (`DS_Store`, etc.)
|
|
- **Node / Vite / React** (`app/node_modules/`, `app/dist/`)
|
|
- **Xcode / Swift** (derived data, `.xcuserdata`, build artifacts)
|
|
- **Python / ComfyUI** (`__pycache__`, `.venv`, model weights)
|
|
- **Infrastructure** (Terraform state, secrets)
|
|
|
|
**You should never commit:**
|
|
- API keys or secrets (`.env` files are ignored)
|
|
- `node_modules/` directory
|
|
- Xcode `DerivedData/` or `.xcuserdata/`
|
|
- Python virtual environments (`.venv/`, `venv/`)
|
|
|
|
### `.gitkeep`
|
|
A `.gitkeep` file is used to **track an otherwise empty directory** in Git (Git does not track empty folders).
|
|
|
|
**When to add one:** If you create a new directory that should be committed but has no files yet, add an empty `.gitkeep` file inside it:
|
|
```bash
|
|
touch path/to/your/new-empty-folder/.gitkeep
|
|
```
|
|
|
|
---
|
|
|
|
## Step 1 — Create a Gitea Issue
|
|
|
|
Every feature or bug fix must start with a **Gitea Issue**. Issues must be created in **Sagnik's upstream repository** — not your fork. The upstream is the source of truth for the project, and `Closes #<N>` in your PR description will only auto-close the issue if it lives in the same repo your PR targets.
|
|
|
|
### Via Browser (Gitea Web UI)
|
|
|
|
1. Go to **Sagnik's upstream repo**: `https://git.desineuron.in/sagnik/Project_Velocity`.
|
|
2. Click on the **Issues** tab.
|
|
3. Click the green **New Issue** button.
|
|
4. Fill in the title using the format:
|
|
```
|
|
feat : <Short description of your feature>
|
|
```
|
|
**Example:**
|
|
```
|
|
feat : Build the native SwiftUI app shell mirroring the WebOS interface
|
|
```
|
|
5. Add a description explaining:
|
|
- **What** you are building.
|
|
- **Why** it is needed.
|
|
- **Acceptance criteria** (what "done" looks like).
|
|
6. Assign the issue to yourself.
|
|
7. Click **Submit**. Note down the **Issue Number** (e.g., `#12`) — you will need it for the branch name.
|
|
|
|
### Via CLI (using `curl` or Gitea API)
|
|
|
|
```bash
|
|
# Replace placeholders before running
|
|
GITEA_URL="https://git.desineuron.in"
|
|
GITEA_TOKEN="<YOUR_PERSONAL_ACCESS_TOKEN>" # Generate at: Profile → Settings → Applications
|
|
REPO_OWNER="sagnik" # Issues go in the UPSTREAM repo
|
|
REPO_NAME="Project_Velocity"
|
|
ISSUE_TITLE="feat : <Short description of your feature>"
|
|
ISSUE_BODY="<Detailed description of what you are building and why>"
|
|
|
|
curl -s -X POST "$GITEA_URL/api/v1/repos/$REPO_OWNER/$REPO_NAME/issues" \
|
|
-H "Content-Type: application/json" \
|
|
-H "Authorization: token $GITEA_TOKEN" \
|
|
-d "{
|
|
\"title\": \"$ISSUE_TITLE\",
|
|
\"body\": \"$ISSUE_BODY\",
|
|
\"assignees\": [\"$REPO_OWNER\"]
|
|
}"
|
|
```
|
|
> The response JSON will contain the `number` field — **this is your issue number**.
|
|
|
|
---
|
|
|
|
## Step 2 — Sync with Upstream Before Branching
|
|
|
|
Before creating a feature branch, **always** pull the latest changes from **`upstream`** (Sagnik's repo) — not from your fork (`origin`). This ensures your work starts from the most up-to-date version of the project.
|
|
|
|
### Via CLI
|
|
|
|
```bash
|
|
# Navigate to your project root
|
|
cd "/path/to/Project_Velocity"
|
|
|
|
# Switch to main
|
|
git checkout main
|
|
|
|
# Fetch all branches from upstream
|
|
git fetch upstream
|
|
|
|
# Merge upstream/main into your local main
|
|
git merge upstream/main
|
|
|
|
# (Optional) Push the synced main to your own fork to keep it up to date
|
|
git push origin main
|
|
```
|
|
|
|
> **Why `upstream` and not `origin`?**
|
|
> `origin` is your personal fork — it only knows about changes you've pushed.
|
|
> `upstream` is Sagnik's repository — the actual source of truth for the project.
|
|
|
|
### Via Antigravity Source Control UI
|
|
|
|
Antigravity's sync button pulls from `origin` by default. To sync from upstream, use the terminal:
|
|
|
|
1. Open a terminal in Antigravity (`Ctrl + `` ` `` ` `).
|
|
2. Run:
|
|
```bash
|
|
git fetch upstream && git merge upstream/main
|
|
```
|
|
3. Then click the **↺ (Refresh)** icon in the Source Control panel to refresh the view.
|
|
4. Confirm the **Graph** section shows your local `main` is aligned with `upstream/main`.
|
|
|
|
---
|
|
|
|
## Step 3 — Create a Feature Branch
|
|
|
|
Branch name format: **`feat/#<ISSUE_NUMBER>`**
|
|
|
|
**IMPORTANT:** Replace `<ISSUE_NUMBER>` with the actual number from Step 1.
|
|
|
|
### Via CLI
|
|
|
|
```bash
|
|
# Make sure you are on main first
|
|
git checkout main
|
|
|
|
# Create and switch to the new branch
|
|
git checkout -b feat/#<ISSUE_NUMBER>
|
|
|
|
# Example:
|
|
# git checkout -b feat/#12
|
|
```
|
|
|
|
### Via Antigravity Source Control UI
|
|
|
|
1. In the **Source Control** panel, look at the bottom **Graph** section.
|
|
2. Click on the **branch name** shown next to the current `HEAD` commit (e.g., `main`).
|
|
3. A branch picker will appear at the top of the screen.
|
|
4. Type the new branch name exactly: `feat/#<ISSUE_NUMBER>`
|
|
5. Select **"Create new branch: feat/#<ISSUE_NUMBER>"** from the dropdown.
|
|
6. Confirm. Your working branch is now set to the new feature branch.
|
|
|
|
---
|
|
|
|
## Step 4 — Make Your Changes & Commit
|
|
|
|
### Stage Your Files
|
|
|
|
#### Via CLI
|
|
|
|
```bash
|
|
# Stage specific files
|
|
git add path/to/changed/file.swift
|
|
|
|
# Stage all changed/new files at once (use with care)
|
|
git add .
|
|
|
|
# Review what is staged before committing
|
|
git status
|
|
```
|
|
|
|
#### Via Antigravity Source Control UI
|
|
|
|
1. In the **Source Control** panel, you will see two sections:
|
|
- **Staged Changes** — files ready to be committed.
|
|
- **Changes** — files that are modified but not yet staged.
|
|
2. To **stage a file**: Hover over it in the **Changes** section and click the **`+`** (plus) icon that appears on the right.
|
|
3. To **unstage a file**: Hover over it in **Staged Changes** and click the **`-`** (minus) icon.
|
|
4. To **stage all changes at once**: Click the **`+`** (plus) icon next to the **Changes** section header.
|
|
|
|
### Write Your Commit Message
|
|
|
|
Use the **Conventional Commits** format:
|
|
```
|
|
<type>(scope): <short summary>
|
|
```
|
|
|
|
| Type | When to Use |
|
|
|------|-------------|
|
|
| `feat` | A new feature |
|
|
| `fix` | A bug fix |
|
|
| `docs` | Documentation changes only |
|
|
| `refactor` | Code restructured, no behavior change |
|
|
| `chore` | Config, build scripts, dependencies |
|
|
| `test` | Adding or fixing tests |
|
|
|
|
**Example commit messages:**
|
|
```
|
|
feat(ios): add Dashboard, Oracle, Sentinel, and Inventory tab views
|
|
|
|
feat(ios): implement AppStore with lead, visitor, and metrics models
|
|
|
|
fix(ios): correct ARSunOverlayView coordinate calculations
|
|
|
|
docs(agent): add velocity_ios_bible.md technical reference
|
|
```
|
|
|
|
### Commit
|
|
|
|
#### Via CLI
|
|
|
|
```bash
|
|
git commit -m "<type>(scope): <short summary of your change>"
|
|
|
|
# Example:
|
|
# git commit -m "feat(ios): add Dashboard, Oracle, Sentinel tab views mirroring WebOS"
|
|
```
|
|
|
|
#### Via Antigravity Source Control UI
|
|
|
|
1. Ensure your files are in the **Staged Changes** section.
|
|
2. Click the **Message** text field at the top of the Source Control panel (placeholder: `Message (⌘Enter to com...)`).
|
|
3. Type your commit message following the Conventional Commits format above.
|
|
4. *(Optional)* Click **Generate ✦** to let Antigravity AI suggest a commit message based on your staged diffs — review it before accepting.
|
|
5. Click the blue **✓ Commit** button (or press `⌘ + Enter`) to commit.
|
|
|
|
---
|
|
|
|
## Step 5 — Push the Branch to Gitea
|
|
|
|
### Via CLI
|
|
|
|
```bash
|
|
# Push your feature branch to the remote (origin)
|
|
git push origin feat/#<ISSUE_NUMBER>
|
|
|
|
# Example:
|
|
# git push origin feat/#12
|
|
```
|
|
|
|
If this is the **first push** of a new branch, Git may ask you to set the upstream:
|
|
```bash
|
|
git push --set-upstream origin feat/#<ISSUE_NUMBER>
|
|
```
|
|
|
|
### Via Antigravity Source Control UI
|
|
|
|
1. After committing, look at the **Changes** header in the Source Control panel.
|
|
2. Click the **`...` (More Actions)** menu (top-right of the Changes section header).
|
|
3. Select **Push** from the dropdown.
|
|
4. Alternatively, click the **↑ (Publish/Push)** cloud icon if visible next to the branch name in the status bar or Graph section.
|
|
5. Antigravity will push your local feature branch to `origin/feat/#<ISSUE_NUMBER>` on Gitea.
|
|
|
|
---
|
|
|
|
## Step 6 — Create a Pull Request (Fork → Upstream)
|
|
|
|
Since you are working on a fork, your PR goes **from your fork's feature branch → Sagnik's upstream `main`**. This is a cross-repository PR.
|
|
|
|
### Via Browser (Gitea Web UI)
|
|
|
|
1. Go to **Sagnik's upstream repo**: `https://git.desineuron.in/sagnik/Project_Velocity`.
|
|
2. Click the **Pull Requests** tab → **New Pull Request**.
|
|
3. Click **"compare across forks"** (Gitea shows this option when creating a cross-fork PR).
|
|
4. Set up the PR direction:
|
|
- **Base repository:** `sagnik/Project_Velocity` — **Base branch:** `main`
|
|
- **Head repository:** `<YOUR_USERNAME>/Project_Velocity` — **Compare branch:** `feat/#<ISSUE_NUMBER>`
|
|
5. Fill in the PR form:
|
|
- **Title:** `feat(scope): <Short description>`
|
|
- **Description:**
|
|
```
|
|
## Summary
|
|
<What does this PR do?>
|
|
|
|
## Changes
|
|
- <List the main changes>
|
|
|
|
## Related Issue
|
|
Closes #<ISSUE_NUMBER>
|
|
```
|
|
6. Assign **Sagnik** as reviewer.
|
|
7. Click **Create Pull Request**.
|
|
|
|
> 💡 **Alternatively**, after you push your branch to your fork (`origin`), Gitea may show a yellow banner inside Sagnik's upstream repo prompting you to create a cross-fork PR automatically. Click that if it appears.
|
|
|
|
### Via CLI (using Gitea API)
|
|
|
|
For a cross-fork PR, the `head` must include your fork username as a prefix.
|
|
|
|
```bash
|
|
GITEA_URL="https://git.desineuron.in"
|
|
GITEA_TOKEN="<YOUR_PERSONAL_ACCESS_TOKEN>"
|
|
UPSTREAM_OWNER="sagnik" # Sagnik's username
|
|
UPSTREAM_REPO="Project_Velocity"
|
|
YOUR_USERNAME="<YOUR_USERNAME>" # Your Gitea username
|
|
FEATURE_BRANCH="feat/#<ISSUE_NUMBER>"
|
|
PR_TITLE="feat(scope): <Short description>"
|
|
PR_BODY="## Summary\n<What does this PR do?>\n\n## Changes\n- <List main changes>\n\n## Related Issue\nCloses #<ISSUE_NUMBER>"
|
|
|
|
curl -s -X POST "$GITEA_URL/api/v1/repos/$UPSTREAM_OWNER/$UPSTREAM_REPO/pulls" \
|
|
-H "Content-Type: application/json" \
|
|
-H "Authorization: token $GITEA_TOKEN" \
|
|
-d "{
|
|
\"title\": \"$PR_TITLE\",
|
|
\"body\": \"$PR_BODY\",
|
|
\"head\": \"$YOUR_USERNAME:$FEATURE_BRANCH\",
|
|
\"base\": \"main\"
|
|
}"
|
|
```
|
|
|
|
> Note the `head` format: `"<YOUR_USERNAME>:feat/#<ISSUE_NUMBER>"` — this tells Gitea the branch lives in your fork, not the upstream.
|
|
|
|
---
|
|
|
|
## Quick Reference — CLI Cheat Sheet
|
|
|
|
Copy and fill in the placeholders (`<...>`) before running.
|
|
|
|
```bash
|
|
# ── ONE-TIME SETUP (do this once per machine) ─────────────────
|
|
cd "/path/to/Project_Velocity"
|
|
git remote add upstream https://git.desineuron.in/sagnik/Project_Velocity.git
|
|
git remote -v # verify: you should see both origin and upstream
|
|
|
|
# ── 1. Create the Gitea Issue ──────────────────────────────────
|
|
# Go to Gitea web UI or use the curl command in Step 1
|
|
# Title format: feat : <Short description>
|
|
# Note the issue number: <ISSUE_NUMBER>
|
|
|
|
# ── 2. Sync from upstream main ────────────────────────────────
|
|
git checkout main
|
|
git fetch upstream
|
|
git merge upstream/main
|
|
git push origin main # keep your fork in sync too
|
|
|
|
# ── 3. Create & switch to feature branch ─────────────────────
|
|
git checkout -b feat/#<ISSUE_NUMBER>
|
|
|
|
# ── 4. Stage & Commit ─────────────────────────────────────────
|
|
git add .
|
|
git status # double-check what is staged
|
|
git commit -m "<type>(scope): <short summary>"
|
|
|
|
# ── 5. Push branch to YOUR FORK (origin) ──────────────────────
|
|
git push origin feat/#<ISSUE_NUMBER>
|
|
|
|
# ── 6. Create Pull Request (fork → upstream) ──────────────────
|
|
# Go to: https://git.desineuron.in/sagnik/Project_Velocity
|
|
# Pull Requests → New Pull Request → Compare across forks
|
|
# head: <YOUR_USERNAME>/Project_Velocity : feat/#<ISSUE_NUMBER>
|
|
# base: sagnik/Project_Velocity : main
|
|
```
|
|
|
|
---
|
|
|
|
## Tips & Best Practices
|
|
|
|
- **One issue = one branch = one PR.** Keep your changes focused.
|
|
- **Always sync from `upstream`, not `origin`.** Your fork doesn't automatically know about changes Sagnik pushes. Run `git fetch upstream && git merge upstream/main` regularly.
|
|
- **Commit often, push when ready.** Small commits make code review easier.
|
|
- **Never commit directly to `main`.** Always work on a feature branch.
|
|
- **Push to `origin`, PR to `upstream`.** Push goes to your fork. The PR targets Sagnik's repo.
|
|
- **Reference issues in PRs.** Using `Closes #<ISSUE_NUMBER>` auto-closes the issue on merge.
|
|
- **Personal Access Token:** Generate it once at `https://git.desineuron.in` → Profile → Settings → Applications → Generate Token. Store it securely (e.g., in your password manager or macOS Keychain).
|
|
- **Keep your fork's `main` clean.** Never push feature work directly to `origin/main` — only merge `upstream/main` into it to stay current.
|