Development Setup
This guide covers everything you need to set up your development environment and submit contributions to NeMo Gym.
Quick Start
Development Commands
Run NeMo Gym Tests:
View Test Coverage:
Configuration Debugging:
CI/CD Requirements
All contributions must pass these automated checks:
Required Checks:
- Unit Tests: All existing tests must pass
- Build Docs: Documentation must build without errors
- Copyright Check: All files must have proper copyright headers
- DCO Signing: All commits must be signed off
- Pre-commit Hooks: Code formatting and linting
Test Requirements:
- At least one test per server you contribute
- Tests must run using
gym env test --resources-server your_server - Use pytest for async testing patterns
Build Docs CI Failures
If the build-docs check fails:
-
Test documentation locally: Preview the Fern docs by running
fern docs devfrom the repository root. -
Common issues:
- Missing docstrings in public functions
- Broken markdown links in README or tutorials
- Invalid MDX syntax
Copyright Header Errors
Error: “Found files with missing copyright”
Solution: Add this header to all new Python files:
DCO and Commit Signing
All NeMo Gym contributions require commit signing and DCO sign-off.
Quick Setup
1. Configure Git Signing (Required)
2. Add Signing Key to GitHub
- Go to GitHub Settings → SSH and GPG keys
- Under “SSH keys” section, find “Signing keys” subsection
- Click “New SSH key” → Set type to “Signing Key”
- Copy your public key:
cat ~/.ssh/id_ed25519.pub - Paste the entire output (including
ssh-ed25519prefix)
3. Test Your Setup
IDE Integration
VSCode Setup
Create/update .vscode/settings.json in your project:
Other IDEs: Enable “Git commit signing” and “Always sign-off” in your Git settings.
Making Signed Commits
Every commit must be signed off using the -s flag:
Troubleshooting
Problem: error: gpg failed to sign the data
Problem: “Signing key not found on GitHub”
- Ensure you copied the complete public key including the
ssh-ed25519prefix - Add the key as a Signing Key (not Authentication Key) on GitHub
- Wait a few minutes for GitHub to process the new key
Problem: IDE not signing commits
- Restart your IDE after configuring Git
- Check IDE Git settings match the command line configuration
- Try committing through the command line first to validate setup
Problem: “DCO sign-off missing”
If you have not pushed yet:
If you already pushed to your PR branch:
Force-pushing is disallowed on branches in the upstream NVIDIA-NeMo/Gym repo. If your PR branch is in a fork and your fork allows force pushes, you can re-sign commits locally and push with --force-with-lease; otherwise, push the signed history to a new branch and update the PR.
Tip: Always use git commit -s when creating commits to avoid this issue.
Alternative: GPG Signing
If you prefer GPG over SSH signing:
Common Issues
Testing Issues
Problem: Tests fail locally but not in CI
- Check Python version (3.12+ required)
- Ensure all dependencies installed:
uv sync --extra dev - Run in clean environment
Problem: Async test failures
- Use
pytest-asynciofor async tests - Mark async tests with
@pytest.mark.asyncio - Ensure proper fixture cleanup
Pre-commit Hook Failures
Problem: Pre-commit hooks fail
Common fixes:
ruff check --fix .for lintingruff format .for formatting- Add copyright headers to new files
Development Workflow
For a small, self-contained change, open a single PR:
- Create a feature branch:
git checkout -b <username>/<feature> - Make changes with tests
- Run local checks:
gym dev test && pre-commit run --all-files - Commit with signoff:
git commit -s -S -m "Your message" - Push and open a PR: ensure all CI checks pass
- Address review feedback and iterate
Stacked Pull Requests
For larger changes, NeMo Gym uses GitHub Stacked PRs: a chain of branches where each PR targets the branch below it, so each layer is reviewed as its own focused diff. See GitHub’s Stacked PRs overview for the concept and PR UI; the mechanics of the gh stack CLI in this repo follow.
Prerequisites
Install the GitHub CLI (gh) v2.0 or later, the gh stack extension, and the agent skill:
gh stack requires OAuth — Personal Access Tokens are rejected during the private preview. If gh auth status shows a github_pat_… token, submit/push/sync fail with exit code 9. Re-authenticate with the web flow:
A stack is created in the repo you push to, and that repo must have the preview enabled — push your branches to the remote that points at NVIDIA-NeMo/Gym. With multiple remotes, set the target once (or pass --remote <name> on each command) and enable conflict memory so commands do not prompt:
Create a Stack
Build the stack bottom-up, one logical change per branch, where each branch depends on the one below it. Keep a contribution self-contained — land code together with its tests in a single PR — and stack genuinely dependent follow-ups (for example, documentation) on top.
submit sets each PR’s base to the branch below it and links them as a stack on GitHub. Run every gh stack command non-interactively: pass branch names to init/add/checkout, --auto to submit, and --json to view. Without these flags the commands prompt or open a TUI and hang.
Update a Stack
Make a change on the branch it belongs to, then rebase the layers above it:
After a PR merges, sync to fast-forward the trunk and rebase the rest of the stack:
On a rebase conflict (exit code 3), resolve the listed files, git add them, then gh stack rebase --continue (or --abort). Merging is done from the GitHub PR UI; CLI merge is not supported yet.
Command Reference
The vendored skill (.claude/skills/gh-stack/SKILL.md) carries the full reference, exit codes, and non-interactive rules for agents.
See the gh-stack documentation for the full feature set.
Questions? Check existing issues or create a new one for guidance.