Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 75 additions & 16 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,41 @@ Thank you for your interest in contributing to Device Connect! This guide will h

## Prerequisites

- Python 3.10+
- Python 3.11+
- Docker & Docker Compose v2
- Git
- [GitHub CLI](https://cli.github.com/) (`gh`) — optional but recommended

## Development Setup

### 1. Fork & clone (first time only)

The easiest path uses the [GitHub CLI](https://cli.github.com/):

```bash
git clone https://github.com/arm/device-connect.git
gh repo fork arm/device-connect --clone
cd device-connect
```

This forks the repo under your account and clones it with `origin` pointing to your fork and `upstream` pointing to `arm/device-connect`.

<details>
<summary>Manual setup (without <code>gh</code>)</summary>

1. Fork via the GitHub UI
2. Clone your fork and add the upstream remote:

```bash
git clone https://github.com/<you>/device-connect.git
cd device-connect
git remote add upstream https://github.com/arm/device-connect.git
```

</details>

### 2. Install dependencies

```bash
python3 -m venv .venv
source .venv/bin/activate

Expand All @@ -39,9 +64,9 @@ See the [README](README.md) for the full architecture overview.
### 1. Create a branch

```bash
git checkout main && git pull origin main
git checkout -b feature/your-feature-name
# or: git checkout -b fix/issue-number-description
git fetch upstream
git checkout -b feature/your-feature-name upstream/main
# or: git checkout -b fix/issue-number-description upstream/main
```

### 2. Make changes
Expand All @@ -50,7 +75,24 @@ git checkout -b feature/your-feature-name
- Add tests for new functionality
- Update documentation if needed

### 3. Commit
### 3. Lint & test

```bash
# Lint (must pass before opening a PR)
ruff check packages/ tests/

# Unit tests — run the package(s) you changed
pytest packages/device-connect-edge/tests/ -v
pytest packages/device-connect-server/tests/ -v
pytest packages/device-connect-agent-tools/tests/test_connection_unit.py \
packages/device-connect-agent-tools/tests/test_tools_unit.py \
packages/device-connect-agent-tools/tests/test_langchain_adapter.py \
packages/device-connect-agent-tools/tests/test_strands_adapter.py -v
```

See [Running Tests](#running-tests) below for integration tests.

### 4. Commit

```bash
git add <specific-files>
Expand All @@ -64,51 +106,68 @@ Closes #123"

Commit message prefixes: `feat`, `fix`, `docs`, `refactor`, `test`, `chore`

### 4. Open a pull request
### 5. Open a pull request

```bash
gh pr create --fill
```

This pushes your branch to your fork and opens a PR against `arm/device-connect:main` in one step.

<details>
<summary>Manual setup (without <code>gh</code>)</summary>

```bash
git push origin feature/your-feature-name
```

Open a PR on GitHub targeting `main`. Include a description of what changed, why, and how to test it.
Then open a PR on GitHub from your fork targeting `arm/device-connect:main`.

</details>

## Running Tests

### Unit tests (no Docker needed)

Run from the repository root:

```bash
# SDK
cd packages/device-connect-edge && python3 -m pytest tests/ -v
# Edge SDK
pytest packages/device-connect-edge/tests/ -v

# Server
cd packages/device-connect-server && python3 -m pytest tests/ -v
pytest packages/device-connect-server/tests/ -v

# Agent tools
cd packages/device-connect-agent-tools && python3 -m pytest tests/test_connection_unit.py tests/test_tools_unit.py -v
pytest packages/device-connect-agent-tools/tests/test_connection_unit.py \
packages/device-connect-agent-tools/tests/test_tools_unit.py \
packages/device-connect-agent-tools/tests/test_langchain_adapter.py \
packages/device-connect-agent-tools/tests/test_strands_adapter.py -v
```

### Integration tests (require Docker)

```bash
cd tests
docker compose -f docker-compose-itest.yml up -d
DEVICE_CONNECT_ALLOW_INSECURE=true python3 -m pytest tests/ -v -m "not llm"
DEVICE_CONNECT_ALLOW_INSECURE=true pytest -v -m "not llm"
docker compose -f docker-compose-itest.yml down -v
```

See [tests/README.md](tests/README.md) for the full test matrix.

## Coding Standards

- **Style**: PEP 8, enforced with `ruff`
- **Line length**: 120 characters
- **Style**: PEP 8, enforced with [`ruff`](ruff.toml)
- **Line length**: 120 characters (configured in [`ruff.toml`](ruff.toml))
- **Type hints**: Use throughout public APIs
- **Naming**: `snake_case` for functions/variables, `PascalCase` for classes, `UPPER_CASE` for constants, `camelCase` for event names (e.g., `taskComplete`, `plateGrasped`)
- **Docstrings**: Google-style
- **Tests**: pytest-asyncio with `asyncio_mode = auto`, mock `@emit` methods with `AsyncMock`
- **Tests**: pytest with pytest-asyncio; `asyncio_mode` varies by package (`auto` in server and integration tests, `strict` in agent-tools). Mock `@emit` methods with `AsyncMock`.

## Pull Request Checklist

- [ ] `ruff check` passes with no errors
- [ ] All unit tests pass
- [ ] Integration tests pass (if applicable)
- [ ] New code has tests
Expand Down
1 change: 1 addition & 0 deletions ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
line-length = 120