Skip to main content

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 needWhy
A GitLab accountSource of truth, merge requests, CI
Membership in the LibESys group or this projectClone and push rights
Git on your workstationBranch, 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:

  1. Check your inbox for a GitLab invitation (or open GitLab → Overview → Invitations).
  2. Accept the invite.
  3. Confirm you see LibESys / esysdox-ops under Projects (or inside the LibESys group).
  4. 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:

  1. Sign in to the same GitLab account they added (work vs personal email).
  2. Open the project URL above while logged in.
  3. If you see Request Access, use it and tell a maintainer (chat, ticket, or email) who you are and what you plan to contribute.
  4. 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:

  1. Identify a maintainer (team lead, or whoever owns LibESys on GitLab).
  2. Send a short request: GitLab username, why you need access, and whether you need Developer (typical) or read-only Reporter (docs review only).
  3. 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)

RoleCan contribute how
ReporterBrowse, comment on MRs; usually cannot push
DeveloperPush branches, open merge requests (default for contributors)
MaintainerMerge to protected branches, change settings

2. Clone and connect Git

SSH key on GitLab

  1. Generate a key if you do not have one (see GitLab SSH keys guide).
  2. Add the public key under GitLab → Preferences → SSH Keys.
  3. 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

From your clone of the repository (after GitLab access and git clone):

PlatformCommand
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).

FlagLinuxWindows
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.


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

BenefitWhat the repo provides
Correct module layoutinstructions.md — architecture, CLI surface, host paths
Safe defaults.cursor/rules/ — commits, destructive ops, integration tests, Python CLI style
Fewer bad git operationsRules tell the agent not to push or commit unless you ask
Faster reviewsAgent 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)

  1. Install Cursor and sign in.
  2. Open folder: File → Open Folder → your esysdox-ops clone.
  3. Trust the workspace when prompted (rules apply only inside this project).
  4. Use Agent mode for multi-file changes; use Ask mode when you only want an explanation.
  5. First prompt idea: “Read instructions.md and summarize how deploy and nginx rollback work” — confirms the agent loaded project context.
  6. Shell: allow the agent to run ruff and pytest when implementing Python changes.
  7. Git: tell the agent which remote to use, e.g. “push to remote gitlab on branch develop using SSH host gitlab-ai” (see SSH guide). Do not paste private keys into chat.
  8. Optional — glab: see GitLab CI with glab below 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 glab and running glab auth login (or GITLAB_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 (--yes for 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 glab per GitLab CI agent access; fix on develop by 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:

  1. Read instructions.md end-to-end once.
  2. Skim .cursor/rules/*.mdc — they are plain Markdown with the same policies Cursor enforces.
  3. Follow the commit checklist before every commit.
  4. 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]
  1. Create a branch from develop (optional but clearer for large work):

    git checkout -b feat/my-short-description
  2. Edit code or docs (see table below).

  3. Run checks (or let Cursor run them).

  4. Commit with a message like:

    feat(project): Add backup size warning to doctor

    Explain why the check matters in the body if needed.

    AI: yes
  5. Push:

    git push -u gitlab HEAD
  6. Wait for ruff, unit, and integration on develop.

  7. When CI is green, update master with a fast-forward only (no merge commit):

    git checkout master && git pull gitlab master
    git merge --ff-only gitlab/develop
    git push gitlab master

    Or open an MR developmaster and use GitLab Fast-forward merge.

  8. To catch up develop with master, use git rebase gitlab/master, not git merge.

  9. 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 typeEdit
User guide or overviewwebsite/docs/
Blog postwebsite/blog/
Python API / docstringssrc/edox_ops/ + docs-api/api/modules.rst
Commit / CI / SSH policyContributor guides
This contributing guidewebsite/docs/contributing.md

Build and preview: Documentation in this repo.

Code

AreaLocation
CLI commandssrc/edox_ops/cli.py + ops modules
Host constantssrc/edox_ops/config.py
Teststests/ (monkeypatch exec.run_command)
CI.gitlab-ci.yml

Match existing patterns: Typer, run_command for subprocesses, --yes on destructive operations, typer errors to stderr.


TopicGuide
SSH keys and gitlab-ai remoteGitLab SSH keys
Branch develop, CI jobs, fixupsGitLab CI
First push and pipelineGitLab getting started
Commit format and AI: footerCommit messages
Pre-commit checklistCommit checklist
glab install, auth, reading CI logsGitLab CI agent access
Agent architecture (Cursor)instructions.md

Quick checklist

  • GitLab access (invite accepted or request approved)
  • SSH key on GitLab; ssh -T works; gitlab-ai configured per SSH guide
  • Clone; on branch develop
  • Dev environment: ./scripts/setup-dev.sh or .\scripts\setup-dev.ps1 (or manual steps above)
  • Cursor installed and repo opened (recommended), or instructions.md read
  • Optional: glab configured 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.