Contributing
This guide takes you from no access to a merged change: joining the GitLab project, setting up your machine, and using Cursor AI (recommended) or a classic editor workflow.
Technical references (SSH keys, CI, commit format) are published under Contributor guides; this page links to them instead of duplicating every policy.
Before you start
| You need | Why |
|---|---|
| A GitLab account | Source of truth, merge requests, CI |
| Membership in the LibESys group or this project | Clone and push rights |
| Git on your workstation | Branch, commit, push |
| Python 3.11+ | Lint, unit tests, local CLI |
| Cursor (strongly recommended) | Project rules, instructions.md, low-friction changes |
Host operations (bootstrap, nginx on a VPS) are optional for most code and doc contributions; integration tests run in Docker on CI and optionally locally.
1. Join the project
The repository is hosted on GitLab:
https://gitlab.com/libesys/esysdox-ops
It is not a public fork-and-forget workflow: you need project access before you can clone or open merge requests.
Path A — You were invited
A maintainer adds you by email or username:
- Check your inbox for a GitLab invitation (or open GitLab → Overview → Invitations).
- Accept the invite.
- Confirm you see LibESys / esysdox-ops under Projects (or inside the LibESys group).
- Your role is usually Developer (push branches, open MRs) or Maintainer (merge, settings). If you only need to propose changes, Developer is enough.
If the invite expired, ask the person who invited you to resend it.
Path B — You already have a GitLab account
If colleagues said you “already have access” but the project does not appear:
- Sign in to the same GitLab account they added (work vs personal email).
- Open the project URL above while logged in.
- If you see Request Access, use it and tell a maintainer (chat, ticket, or email) who you are and what you plan to contribute.
- If you get 404 Project Not Found, the project is private and you are not a member yet — contact a LibESys maintainer; they must add you to the group or project.
Path C — You need to ask to join
When you are not on the member list:
- Identify a maintainer (team lead, or whoever owns LibESys on GitLab).
- Send a short request: GitLab username, why you need access, and whether you need Developer (typical) or read-only Reporter (docs review only).
- After approval, accept any invitation and verify you can open the project page without a 404.
There is no separate “signup code” for this repo — access is granted on GitLab only.
Path D — You only need to read the docs
Published product docs may be available without clone access (see the site linked from the project README). To change code or guides, you still need Path A, B, or C.
Roles (quick reference)
| Role | Can contribute how |
|---|---|
| Reporter | Browse, comment on MRs; usually cannot push |
| Developer | Push branches, open merge requests (default for contributors) |
| Maintainer | Merge to protected branches, change settings |
2. Clone and connect Git
SSH key on GitLab
- Generate a key if you do not have one (see GitLab SSH keys guide).
- Add the public key under GitLab → Preferences → SSH Keys.
- Test:
ssh -T git@gitlab.com(welcome message with your username).
This repository’s maintainers use a dedicated SSH host alias gitlab-ai for the
canonical remote. Follow the full
SSH keys and gitlab-ai setup
so git push uses the intended key (especially if you use multiple keys or Cursor runs
git in your shell).
Clone
git clone git@gitlab-ai:libesys/esysdox-ops.git
cd esysdox-ops
HTTPS (if you prefer a personal access token):
git clone https://gitlab.com/libesys/esysdox-ops.git
Confirm the remote:
git remote -v
# expect: gitlab → git@gitlab-ai:libesys/esysdox-ops.git (or your HTTPS URL)
Working branch
Day-to-day work happens on develop, not directly on master:
git fetch gitlab
git checkout develop
git pull gitlab develop
CI runs on pushes to develop. When the pipeline is green, fast-forward master to
develop (git merge --ff-only) — no merge commit. Details:
GitLab CI guide.
3. Development environment
Automated setup (recommended)
From your clone of the repository (after GitLab access and git clone):
| Platform | Command |
|---|---|
| Linux / macOS | ./scripts/setup-dev.sh |
| Windows (PowerShell) | .\scripts\setup-dev.ps1 |
The scripts check Python 3.11+ first (clear install hints if missing), create .venv,
run pip install -e ".[dev]", install pre-commit and both hook types, then run ruff
and pytest (same as CI lint + unit). At the end they can offer to install glab
(with confirmation) and offer glab auth login (interactive; tokens are not stored
by the script).
| Flag | Linux | Windows |
|---|---|---|
| Skip verify | --skip-verify | -SkipVerify |
| Docs site deps | --with-docs | -WithDocs |
| Fresh venv | --recreate-venv | -RecreateVenv |
| Install glab without prompt | --install-glab | -InstallGlab |
| Skip glab prompts | --no-glab | -NoGlab |
glab install: Windows uses winget; macOS uses brew; Linux tries snap or apt
when available. glab auth always needs you (browser or token) — see
GitLab CI agent access.
They print a reminder for steps that stay manual (SSH, develop, Cursor).
Manual setup
python -m venv .venv
# Linux/macOS:
source .venv/bin/activate
# Windows:
.venv\Scripts\activate
pip install -e ".[dev]"
pip install pre-commit
pre-commit install
pre-commit install --hook-type commit-msg
Verify locally (same as CI lint + unit)
ruff check src tests scripts/pre_commit scripts/gitlint_rules.py
ruff format --check src tests scripts/pre_commit scripts/gitlint_rules.py
python -m pytest -q --cov=edox_ops
On Windows, if ruff is not on PATH, use Docker or rely on pre-commit / CI (see
README).
Integration tests (Linux/Docker):
bash tests/integration/run_docker.sh
Windows: .\test.ps1
Documentation site (optional)
If you edit website/ or docs-api/:
pip install -e ".[docs]"
cd website && npm install && npm start
See Documentation in this repo.
Git author (this repository)
Commits must list the human operator as author, even when Cursor helped write the diff. Configure this clone only (example — use your own name and email):
git config user.name "Your Name"
git config user.email "you@example.com"
Record AI help in the commit footer (AI: yes) and/or
Co-authored-by: Cursor <cursoragent@cursor.com> — not as the Git Author. See
commit messages.
4. Recommended: contribute with Cursor AI
We strongly recommend Cursor for work in this repository. The repo ships context so the agent understands layout, safety rules, and CI — you spend less time explaining paths and conventions.
Why Cursor fits this project
| Benefit | What the repo provides |
|---|---|
| Correct module layout | instructions.md — architecture, CLI surface, host paths |
| Safe defaults | .cursor/rules/ — commits, destructive ops, integration tests, Python CLI style |
| Fewer bad git operations | Rules tell the agent not to push or commit unless you ask |
| Faster reviews | Agent can run ruff/pytest and read CI docs when you grant shell access |
Without Cursor, you should read instructions.md and the same rules manually before
touching project_ops, nginx rollback, or deploy paths.
Setup checklist (Cursor)
- Install Cursor and sign in.
- Open folder:
File → Open Folder→ youresysdox-opsclone. - Trust the workspace when prompted (rules apply only inside this project).
- Use Agent mode for multi-file changes; use Ask mode when you only want an explanation.
- First prompt idea: “Read
instructions.mdand summarize how deploy and nginx rollback work” — confirms the agent loaded project context. - Shell: allow the agent to run
ruffandpytestwhen implementing Python changes. - Git: tell the agent which remote to use, e.g. “push to remote
gitlabon branchdevelopusing SSH hostgitlab-ai” (see SSH guide). Do not paste private keys into chat. - Optional —
glab: see GitLab CI withglabbelow so you or the agent can read pipeline results after a push.
GitLab CI with glab (optional)
The setup scripts can install glab after you confirm (or pass --install-glab /
-InstallGlab). You still run glab auth login yourself once.
Install, authentication, and example commands are documented in Letting an agent read GitLab CI results — that guide covers:
- Installing
glaband runningglab auth login(orGITLAB_TOKEN) - Token scopes for a private project
- Commands such as
glab ci list,glab ci status, and fetching job logs - Pasting logs when you prefer not to configure CLI access
You do not need glab to contribute; the GitLab web UI is enough. It helps when Cursor
or another agent should inspect CI failures in your shell without you copying logs each
time.
Working effectively with the agent
- Be explicit: slug names, command flags (
--yesfor destructive ops), and whether you want a commit or only a patch. - Scope: ask for minimal diffs; the rules match the maintainers’ review style.
- Commits: ask the agent to draft messages per
Conventional Commits;
you run or approve
git commit(hooks run gitlint). - CI failures: paste the job log, or use
glabper GitLab CI agent access; fix ondevelopby amending or fixup per CI guide — avoid orphan “fix CI” commits on the working branch.
If you cannot use Cursor
Use any editor (VS Code, PyCharm, vim) and treat instructions.md as your onboarding
doc:
- Read
instructions.mdend-to-end once. - Skim
.cursor/rules/*.mdc— they are plain Markdown with the same policies Cursor enforces. - Follow the commit checklist before every commit.
- Run ruff and pytest locally; open a merge request and wait for GitLab CI
(
ruff,unit,integration).
You can contribute fully without AI; expect more manual reading of src/edox_ops/ and
the guides under Contributor guides.
5. Make a change and open a merge request
Typical flow
flowchart LR
access[GitLab access] --> clone[Clone + checkout develop]
clone --> env[venv + pre-commit]
env --> change[Edit code or docs]
change --> check[ruff + pytest]
check --> commit[Commit with conventional message]
commit --> push[git push gitlab develop]
push --> ci[GitLab CI green]
ci --> ff[Fast-forward master to develop]
-
Create a branch from
develop(optional but clearer for large work):git checkout -b feat/my-short-description -
Edit code or docs (see table below).
-
Run checks (or let Cursor run them).
-
Commit with a message like:
feat(project): Add backup size warning to doctorExplain why the check matters in the body if needed.AI: yes -
Push:
git push -u gitlab HEAD -
Wait for ruff, unit, and integration on
develop. -
When CI is green, update
masterwith a fast-forward only (no merge commit):git checkout master && git pull gitlab mastergit merge --ff-only gitlab/developgit push gitlab masterOr open an MR
develop→masterand use GitLab Fast-forward merge. -
To catch up
developwithmaster, usegit rebase gitlab/master, notgit merge. -
Address review comments on
develop; push updates to the same branch.
First-time push and pipeline overview: GitLab getting started.
6. What to edit
Documentation
| Change type | Edit |
|---|---|
| User guide or overview | website/docs/ |
| Blog post | website/blog/ |
| Python API / docstrings | src/edox_ops/ + docs-api/api/modules.rst |
| Commit / CI / SSH policy | Contributor guides |
| This contributing guide | website/docs/contributing.md |
Build and preview: Documentation in this repo.
Code
| Area | Location |
|---|---|
| CLI commands | src/edox_ops/cli.py + ops modules |
| Host constants | src/edox_ops/config.py |
| Tests | tests/ (monkeypatch exec.run_command) |
| CI | .gitlab-ci.yml |
Match existing patterns: Typer, run_command for subprocesses, --yes on destructive
operations, typer errors to stderr.
7. Related guides
| Topic | Guide |
|---|---|
SSH keys and gitlab-ai remote | GitLab SSH keys |
Branch develop, CI jobs, fixups | GitLab CI |
| First push and pipeline | GitLab getting started |
Commit format and AI: footer | Commit messages |
| Pre-commit checklist | Commit checklist |
glab install, auth, reading CI logs | GitLab CI agent access |
| Agent architecture (Cursor) | instructions.md |
Quick checklist
- GitLab access (invite accepted or request approved)
- SSH key on GitLab;
ssh -Tworks;gitlab-aiconfigured per SSH guide - Clone; on branch
develop - Dev environment:
./scripts/setup-dev.shor.\scripts\setup-dev.ps1(or manual steps above) - Cursor installed and repo opened (recommended), or
instructions.mdread - Optional:
glabconfigured per GitLab CI agent access - Local ruff + pytest green (or CI fixes planned)
- Commit message follows conventional format +
AI:footer when applicable - Push to
gitlab; MR opened; CI green
Questions about access or roles: contact your LibESys maintainer on GitLab, not via public issues if the project is private.