GitHub Workflow Guideยถ
This mini-handbook covers the daily Git tasks we use on mcp-context-forge - from the first clone to the last merge.
1. One-Time Setupยถ
# Fork on GitHub from https://github.com/IBM/mcp-context-forge.git first, then:
git clone https://github.com/<your-user>/mcp-context-forge.git
cd mcp-context-forge
# Add the canonical repo so you can pull upstream changes
git remote add upstream https://github.com/IBM/mcp-context-forge.git
git remote -v # sanity-check remotes
1.5 Installing GitHub CLI (gh
)ยถ
macOS (Homebrew)ยถ
Windows (winget)ยถ
While you can run all this through Powershell, the recommended way to develop on Windows is through WSL2 and Visual Studio Code. The same steps as Ubuntu/Debian apply.
Ubuntu / Debianยถ
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | \
sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | \
sudo tee /etc/apt/sources.list.d/github-cli.list
sudo apt update
sudo apt install gh
Fedora / RHELยถ
Tip: Replace the version number (
2.74.0
) with the latest release from https://github.com/cli/cli/releases.
First-time authenticationยถ
Choose:
- GitHub.com
- HTTPS
- Either Paste an authentication token or Authorize in browser.
Verify configurationยถ
gh auth status # should say "Logged in to github.com as <your-user>"
gh repo view # shows repo info if run inside a clone
Everyday commandsยถ
Command | Purpose |
---|---|
gh pr checkout <id> | Fetch & switch to a PR locally (used in ยง4). |
gh pr create -w | Create a PR and open it in the browser. |
gh pr status | Show which PR is checked out and any requested reviews. |
gh pr merge <id> | Squash / rebase / merge the PR from the terminal. |
1.6 Personal Git Configuration (Recommended)ยถ
Setting a few global Git options makes everyday work friction-free and guarantees that every commit passes DCO checks.
1.6.1 Commit templateยถ
Create a single-line template that Git pre-pends to every commit message so you never forget the sign-off:
1.6.2 ~/.gitconfig
exampleยถ
Put this in ~/.gitconfig
(or append the bits you're missing):
# ~/.gitconfig
[user]
name = <Your Name>
email = <you@example.com>
[init]
defaultBranch = main # Use 'main' instead of 'master' when creating new repos
[core]
autocrlf = input # On commit: convert CRLF to LF (Windows โ Linux)
eol = lf # Ensure all files in the repo use LF internally
[alias]
cm = commit -s -m # `git cm "message"` โ signed commit
ca = commit --amend -s # `git ca` โ amend + sign-off
[commit]
template = ~/.git-commit-template
Or run the one-liners:
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
git config --global alias.cm "commit -s -m"
git config --global alias.ca "commit --amend -s"
git config --global commit.template ~/.git-commit-template
Replace placeholders with your real details, and you're good to go.
2. Staying in Sync with Upstreamยถ
# From any branch:
git fetch upstream
git switch main # or master, depending on the project
git merge --ff-only upstream/main
git push origin main # keep your fork up to date
3. Creating Your Own Work Branchยถ
git switch -c feat/my-great-idea
# ...hack away...
git add .
# Always sign your commits for DCO compliance:
git commit -s -m "feat: explain context-merging algorithm"
git push -u origin HEAD # publishes the branch
# Then open a Pull Request (PR) on GitHub.
Why
-s
? The-s / --signoff
flag appends aSigned-off-by: Your Name <email>
trailer that lets CI verify Developer Certificate of Origin (DCO) compliance.
4. Fetching & Reviewing an Existing PRยถ
4.1 With Plain Git (works everywhere)ยถ
4.2 With GitHub CLI (fastest if installed)ยถ
5. Smoke-Testing Every PR Before You Comment ๐ยถ
Hard rule: No PR gets a "Looks good to me" without passing both the local and container builds below.
5.1 Local build (SQLite + self-signed HTTPS)ยถ
- Sets up a Python virtualenv
- Installs runtime + dev dependencies
- Runs the HTTPS dev server against SQLite
5.2 Container build (PostgreSQL + Redis)ยถ
make docker-prod # build the lite runtime image locally
make compose-up # start the Docker Compose stack (PostgreSQL + Redis)
- Spins up the full Docker Compose stack
- Uses PostgreSQL for persistence and Redis for queueing
- Rebuilds/uses your freshly built image so you catch Docker-specific issues
5.3 Gateway JWT (local API access)ยถ
Quickly confirm that authentication works and the gateway is healthy:
export MCPGATEWAY_BEARER_TOKEN=$(python3 -m mcpgateway.utils.create_jwt_token -u admin@example.com --secret my-test-key)
curl -s -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" http://localhost:4444/health
Expected output:
If you see anything other than {"status":"healthy"}
, investigate before approving the PR.
Quickly confirm that the MCP Gateway is configured with the correct database, and it is reachable:
Then proceed to register an MCP Server under Gateways using the UI, ensuring that Tools work, creating a Virtual Server and testing that from UI, API and a MCP Client.
These steps are described in Basic Testing.
5.4 Run the automated test suiteยถ
All tests must pass locally. If you add or modify functionality, ensure new tests cover the change.
5.5 Lint & static analysisยถ
Code should come back clean. Fix any warnings before pushing.
If any of the above steps fail, leave a review requesting fixes and paste the relevant logs inline or as a gist.
6. Squashing Commits ๐ฅยถ
Keeping a clean, single-commit history per PR makes git bisect
and blame easier.
6.1 Squash interactively (local, recommended)ยถ
# In your feature branch, before pushing OR after addressing review feedback:
git fetch upstream # make sure refs are fresh
git rebase -i upstream/main
In the interactive list, mark the first commit as pick
and every subsequent one as squash
(or fixup
for no extra message). Save & quit; Git opens an editor so you can craft the final commit message-remember to keep the Signed-off-by
line!
If the branch is already on GitHub and you've squashed locally, force-push the updated, single-commit branch:
6.2 Squash via GitHub UI (simple, but last-minute)ยถ
- In the PR, click "Merge" โ "Squash and merge."
- Tweak the commit title/description as needed.
- Ensure the
Signed-off-by:
trailer is present (GitHub adds it automatically if you enabled DCO in the repo).
Use the UI method only if reviewers are done-every push re-triggers CI.
7. Functional & Code Review Checklistยถ
Check | Why it matters |
---|---|
Does it build locally? | Fastest signal that the code even compiles. |
Does it build in Docker? | Catches missing OS packages or env-var mishaps. |
Unit tests green? | Ensures regressions are caught immediately. |
No new lint errors? | Keeps the CI pipeline and codebase clean. |
Commits squashed & signed? | One commit history + DCO compliance. |
Docs / comments updated? | Future devs will thank you. |
8. Merging the PRยถ
- Squash-and-merge is the default merge strategy.
- Confirm the final commit message follows Conventional Commits and retains a
Signed-off-by:
trailer. - GitHub automatically deletes the source branch after a successful merge-no manual cleanup required.
Verify GitHub CI status checks
Before requesting review, confirm that all required status checks on the PR page are green โ ("All checks have passed"). You should now see something like:
Secure Docker Build / docker-image โ
Successful in ~4m
Build Python Package / python-package (3.11) โ
Successful in ~2m
Tests & Coverage / pytest โ
Successful in ~3m
Lint & Static Analysis / lint โ
Successful in ~2m
Bandit / bandit โ
Successful in ~1m
CodeQL โ
Successful in ~1m
Dependency Review / dependency-review โ
Successful in seconds
DCO โ
Passed
If anything is red or still running, wait or push a fix in the same PR until every line is green. Ensure that a CODEOWNER is assigned to review the PR.
Once the PR is merged, double-check that the CI/CD pipeline deploys the change to all environments without errors.
If any of the above steps fail after the PR is merged or cannot deploy, leave a review requesting fixes and paste the relevant logs inline or as a gist.
9. Cleaning Up Locallyยถ
After the PR is merged: * Switch back to the main branch * Delete the local feature branch * Prune deleted remote branches
git switch main
git branch -D pr-29 # or the feature branch name (replace pr-29 with your branch name)
git fetch -p # prune remotes that GitHub deleted
10. Handy Git Aliases (Optional)ยถ
git config --global alias.co checkout
git config --global alias.cm 'commit -s -m'
git config --global alias.ca 'commit --amend -s'
git config --global alias.rb "rebase -i --autosquash"
git config --global alias.pr '!f() { git fetch upstream pull/$1/head:pr-$1 && git switch pr-$1; }; f'
git pr 42
to fetch-and-switch to PR #42 in one go. These aliases are optional, but they save time and make Git commands easier to type. 11. Troubleshooting FAQยถ
Symptom | Fix |
---|---|
error: cannot lock ref | Run git gc --prune=now and retry. |
docker: no space left | docker system prune -af && docker volume prune |
Unit tests hang on macOS | Ensure you aren't on an Apple-Silicon image that needs platform flags. |
Happy hacking! ๐ ๏ธยถ
Submit improvements to this doc via another signed, squashed PR so everyone benefits.