Skip to content

Commit 0691dc5

Browse files
q-soriartyclaude
andauthored
docs(config): update docs for CI rules and ADS architecture (#118)
- CLAUDE.md: replace ADS-over-MQTT with direct ADS references, add CI Checks section with gotchas (pull_request_target, header/body limits, npm cache, PR title re-trigger) - CONTRIBUTING.md: add ci scope, document hard CI rules (header 72, body 100, subject-case disabled), add CI Checks section - GIT_WORKFLOW.md: add ci scope, fix body wrap limit (100 not 72), remove lowercase subject rule, add PR title validation note and CLA check step Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 4afe6e3 commit 0691dc5

File tree

3 files changed

+96
-27
lines changed

3 files changed

+96
-27
lines changed

CLAUDE.md

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,30 @@ FlowForge is a visual no-code PLC programming environment inspired by Unreal Eng
88

99
## Architecture
1010

11-
Four main components: **Visual Editor** (web frontend) → **.NET Backend API****PLC Build Server(s)** + **Monitor Server(s)** → Beckhoff PLC via ADS over MQTT.
11+
Four main components: **Visual Editor** (web frontend) → **.NET Backend API****PLC Build Server(s)** + **Monitor Server(s)** → Beckhoff PLC via direct ADS (Beckhoff.TwinCAT.Ads).
1212

13-
- `src/shared/FlowForge.Shared/` — Common DTOs, enums, MQTT topic constants. No external dependencies.
13+
- `src/shared/FlowForge.Shared/` — Common DTOs (Flow, Build, Deploy, Project, Target, Auth, Monitor, Ads), enums, MQTT topic constants. No external dependencies.
1414
- `src/frontend/` — Web-based node editor (React + TypeScript + React Flow + Zustand + React Query); feature-based folder structure with auth (Keycloak), layout, and feature modules (editor, projects, build, deploy, targets, monitoring, admin)
1515
- `src/backend/` — Clean Architecture Lite (3 projects):
1616
- `src/backend/src/FlowForge.Backend.Api/` — ASP.NET Core API (Controllers, Middleware, Auth, SignalR hubs). References Application + Infrastructure + Shared.
1717
- `src/backend/src/FlowForge.Backend.Application/` — Business logic, entities, service/repository interfaces. References Shared only.
1818
- `src/backend/src/FlowForge.Backend.Infrastructure/` — EF Core, external integrations (Git, MQTT, Docker, Keycloak, AES encryption). References Application + Shared.
19-
- `src/build-server/` — PLC build server (C#/.NET); pipeline architecture with sequential build steps (IBuildStep), code generation (INodeTranslator strategy pattern), TwinCAT COM facades (IVisualStudioInstance, IAutomationInterface). References Shared.
20-
- `src/monitor-server/` — On-demand PLC monitoring container (C#/.NET, SignalR, MQTTnet); typed hub interface, subscription manager, MQTT ADS client. References Shared.
21-
- `doc/` — Architecture docs (`ARCHITECTURE.md`, `BUILD_SERVER_DESIGN.md`, `MODULE_ARCHITECTURE.md`), decision log, tech decisions
19+
- `src/build-server/` — PLC build server (C#/.NET); pipeline architecture with sequential build steps (IBuildStep), code generation (INodeTranslator strategy pattern), TwinCAT COM facades (IVisualStudioInstance, IAutomationInterface), ADS deploy client (IAdsDeployClient). References Shared. Uses `Beckhoff.TwinCAT.Ads` for direct PLC communication.
20+
- `src/monitor-server/` — On-demand PLC monitoring container (C#/.NET, SignalR); typed hub interface, subscription manager, direct ADS client (IAdsClient) via `Beckhoff.TwinCAT.Ads` + `Beckhoff.TwinCAT.Ads.TcpRouter` for Linux/Docker. References Shared.
21+
- `doc/` — Architecture docs (`ARCHITECTURE.md`, `BUILD_SERVER_DESIGN.md`, `MODULE_ARCHITECTURE.md`, `ADS_INTEGRATION.md`), decision log, tech decisions
2222
- `samples/` — Example visual programs
2323
- `test/` — xUnit + NSubstitute + FluentAssertions test projects: `FlowForge.Shared.Tests`, `FlowForge.Backend.Api.Tests`, `FlowForge.Backend.Application.Tests`, `FlowForge.Backend.Infrastructure.Tests`, `FlowForge.BuildServer.Tests`, `FlowForge.MonitorServer.Tests`
2424
- `src/FlowForge.sln` — Root solution including all .NET projects
2525

2626
**Key architectural decisions:**
27+
- **Direct ADS communication**: Monitor Server uses `Beckhoff.TwinCAT.Ads` + `TcpRouter` (Linux/Docker); Build Server uses `Beckhoff.TwinCAT.Ads` natively (Windows). MQTT is for FlowForge internal messaging only (build notifications, deploy status), NOT for ADS relay. See `doc/ADS_INTEGRATION.md`.
2728
- **Keycloak as auth layer**: all authentication/authorization via Keycloak (local users, LDAP federation, external SSO — all Keycloak config). Backend only validates JWT from Keycloak. User management via FlowForge admin UI (facade over Keycloak Admin REST API).
2829
- **Git repo as single source of truth** on GitHub — each project is a repo containing flow JSON (user-edited) and generated PLC solution (build server output); users commit/push with their own identity; service user handles repo creation only
2930
- **Git-backed workflow**: backend handles git operations for open (fetch) and save (commit/push); build server clones repo, generates TwinCAT solution, commits/pushes back; PostgreSQL stores only metadata, auth, target registry, audit
3031
- **Machine type templates** for new projects (e.g., 3-axis standalone, 3+1 axis standalone, x-division rotary table)
31-
- **Build and Deploy are separate operations with permission hierarchy**: Deploy permission implies Build permission. Deploy button triggers Build + Deploy sequentially; Build button triggers Build only. Build generates PLC solution and commits to repo; Deploy activates on target PLC via ADS over MQTT — both executed by the build server (requires TwinCAT Engineering). Backend orchestrates, build server executes. Deploy lock and 4-eyes principle for production.
32+
- **Build and Deploy are separate operations with permission hierarchy**: Deploy permission implies Build permission. Deploy button triggers Build + Deploy sequentially; Build button triggers Build only. Build generates PLC solution and commits to repo; Deploy activates on target PLC via direct ADS — both executed by the build server (requires TwinCAT Engineering). Backend orchestrates, build server executes. Deploy lock and 4-eyes principle for production.
3233
- **Build queue**: PostgreSQL-based queue with MQTT notify; backend inserts jobs, build servers poll via REST with `FOR UPDATE SKIP LOCKED`; MQTT is lightweight wake-up signal only
3334
- **Build servers are version-specific** (one per TwinCAT version on separate Windows Servers); target runtime readable via ADS enables automatic build server selection
34-
- **PLC activation via ADS over MQTT** through a central MQTT broker (free, no per-server ADS route config needed)
3535
- **Deploy safety**: target labeling/grouping, deploy protection for production targets (4-eyes principle), deploy lock on running PLCs, full audit trail via git history
3636
- **Infrastructure**: Single Docker Compose stack (frontend/nginx, backend, Keycloak, PostgreSQL, MQTT broker, Traefik, docker-socket-proxy). Monitor containers created on-demand via docker-socket-proxy, auto-discovered by Traefik via Docker labels. Build server external on Windows Server (TwinCAT Engineering requirement), connects via REST + MQTT.
3737

@@ -69,26 +69,73 @@ cd src/frontend && npm run dev
6969

7070
## Commit Conventions
7171

72-
Commits are validated by commitlint via husky git hook. **All commits must follow Conventional Commits format:**
72+
Commits are validated by commitlint via husky git hook **and** by GitHub Actions CI on PRs. Both commit messages AND PR titles must pass validation.
73+
74+
**All commits must follow Conventional Commits format:**
7375

7476
```
7577
<type>[optional scope]: <description>
78+
79+
[optional body]
80+
81+
[optional footer(s)]
7682
```
7783

7884
Types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`
7985

80-
Scopes: `frontend`, `backend`, `build-server`, `monitor-server`, `docs`, `config`, `ci`, `deps`
86+
Scopes (warning-level, not required): `frontend`, `backend`, `build-server`, `monitor-server`, `docs`, `config`, `ci`, `deps`
87+
88+
**Hard rules enforced by CI:**
89+
- `header-max-length`: **72 characters max** (includes type, scope, colon, space, and description)
90+
- `body-max-line-length`: **100 characters max** per line in commit body
91+
- `subject-empty`: subject must not be empty
92+
- `subject-full-stop`: no trailing period
93+
- `body-leading-blank`: blank line between header and body
94+
- `footer-leading-blank`: blank line before footer
95+
- `subject-case`: **disabled** (acronyms like DTO, MQTT, TwinCAT are common)
96+
97+
**PR titles** are also validated against the same rules. Keep PR titles under 72 characters.
8198

82-
Rules: imperative mood, lowercase subject, no trailing period, max 72 chars. Use `!` after type/scope for breaking changes.
99+
Use `!` after type/scope for breaking changes. Use imperative mood, no trailing period.
100+
101+
## CI Checks
102+
103+
Every PR runs two GitHub Actions checks:
104+
105+
1. **Validate Commit Messages** (`commitlint.yml`): validates all PR commits AND the PR title against `.commitlintrc.json` rules. Triggered on `opened`, `synchronize`, `reopened` events.
106+
2. **CLA Assistant** (`cla.yml`): checks Contributor License Agreement signature. Uses `pull_request_target` (reads workflow from `main` branch). Signatures stored on `cla-signatures` branch. Org members in allowlist skip signing.
107+
108+
**Important CI notes:**
109+
- CLA workflow reads from `main` branch (`pull_request_target` event) — changes to `cla.yml` must be merged to `main` first (via hotfix) to take effect
110+
- Commitlint workflow reads `.commitlintrc.json` from the PR branch — rule changes take effect after rebase on `develop`
111+
- PR title changes do NOT trigger CI re-runs (no `edited` event) — push a commit to trigger `synchronize`
112+
- `package-lock.json` is in `.gitignore` — do NOT use `cache: 'npm'` in GitHub Actions setup-node steps
83113

84114
## Git Workflow
85115

86116
Uses **GitFlow** branching model:
87-
- `main` — production releases (tagged with semver)
88-
- `develop` — integration branch
117+
- `main` — production releases (tagged with semver), protected branch
118+
- `develop` — integration branch, protected branch
89119
- `feature/*` — new features (from/to `develop`)
90120
- `bugfix/*` — bug fixes (from/to `develop`)
91121
- `release/*` — release prep (from `develop`, merge to both `main` and `develop`)
92122
- `hotfix/*` — emergency fixes (from `main`, merge to both `main` and `develop`)
123+
- `cla-signatures` — CLA signature storage (unprotected, used by CLA bot)
93124

94125
PRs target `develop` for features/bugfixes. Squash-merge for feature branches, merge commit for release/hotfix branches.
126+
127+
**Release process:**
128+
1. Create `release/x.y.z` from `develop`
129+
2. Update `CHANGELOG.md` (move Unreleased to new version section)
130+
3. Commit, push, create PR to `main`
131+
4. Merge to `main` with merge commit (not squash)
132+
5. Tag `main` with `vx.y.z`
133+
6. Merge `main` back to `develop`
134+
7. Delete release branch (local + remote)
135+
136+
**Hotfix process** (for CI/workflow fixes that need to be on `main` immediately):
137+
1. Create `hotfix/*` from `main`
138+
2. Fix, commit, push, create PR to `main`
139+
3. Merge to `main` with merge commit
140+
4. Cherry-pick to `develop` (or merge `main` into `develop`)
141+
5. Delete hotfix branch

CONTRIBUTING.md

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ All commit messages **MUST** follow the [Conventional Commits](https://www.conve
135135
- `monitor-server` - Monitor server changes
136136
- `docs` - Documentation
137137
- `config` - Configuration files
138+
- `ci` - CI/CD configuration
138139
- `deps` - Dependencies
139140

140141
**Examples:**
@@ -183,20 +184,32 @@ git commit -m "your message"
183184
# ❌ Commit message does not follow Conventional Commits format
184185
```
185186

187+
**Hard Rules (enforced by CI):**
188+
- **Header max 72 characters** (includes `type(scope): ` prefix — plan accordingly)
189+
- **Body lines max 100 characters** each
190+
- No trailing period in subject
191+
- Blank line between header and body
192+
- Subject must not be empty
193+
- `subject-case` is **disabled** (acronyms like DTO, MQTT, TwinCAT are common)
194+
195+
**PR titles** are also validated against the same rules — keep them under 72 characters.
196+
186197
**Good Practices:**
187198
- Use present tense: "add feature" not "added feature"
188199
- Use imperative mood: "fix bug" not "fixes bug"
189-
- Keep first line under 72 characters
190200
- Reference issues: `Closes #123`, `Fixes #456`, `Relates to #789`
191201
- Write descriptive body for complex changes
192202

193-
#### Coding Standards
203+
#### CI Checks
194204

195-
Once technology stack is finalized, we'll establish:
196-
- Code formatting rules (ESLint, Prettier, etc.)
197-
- Naming conventions
198-
- Documentation requirements
199-
- Testing requirements
205+
Every PR runs two automated checks:
206+
207+
1. **Validate Commit Messages** — validates all PR commits AND the PR title against `.commitlintrc.json`
208+
2. **CLA Assistant** — checks Contributor License Agreement signature (first-time contributors only; org members are allowlisted)
209+
210+
Both checks must pass before merge. See [CLAUDE.md](CLAUDE.md#ci-checks) for detailed CI notes.
211+
212+
#### Coding Standards
200213

201214
**Current Standards:**
202215
- Use meaningful variable and function names

doc/GIT_WORKFLOW.md

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -202,17 +202,19 @@ git push origin --delete hotfix/critical-bug-fix
202202
- `monitor-server` - Monitor server (src/monitor-server/)
203203
- `docs` - Documentation
204204
- `config` - Configuration files
205+
- `ci` - CI/CD configuration
205206
- `deps` - Dependencies
206207

207208
### Guidelines
208209

209210
1. **Use imperative mood**: "add feature" not "added feature"
210-
2. **Lowercase subject**: `feat: add feature` not `feat: Add feature`
211-
3. **No period at end**: `fix: resolve bug` not `fix: resolve bug.`
212-
4. **Max 72 characters** for subject line
211+
2. **No period at end**: `fix: resolve bug` not `fix: resolve bug.`
212+
3. **Max 72 characters** for header (includes `type(scope): ` prefix)
213+
4. **Max 100 characters** per line in body
213214
5. **Separate subject from body** with blank line
214-
6. **Wrap body at 72 characters**
215-
7. **Reference issues**: `Closes #123`, `Fixes #456`
215+
6. **Reference issues**: `Closes #123`, `Fixes #456`
216+
217+
> **Note**: `subject-case` is disabled — acronyms (DTO, MQTT, TwinCAT) are common in this project.
216218
217219
### Breaking Changes
218220

@@ -254,14 +256,16 @@ See migration guide in docs/MIGRATION.md"
254256

255257
### PR Title Format
256258

257-
PR titles should follow Conventional Commits:
259+
PR titles are validated by CI against the same commitlint rules. **Keep titles under 72 characters.**
258260

259261
```
260262
feat(frontend): add visual timer node component
261263
fix(backend): resolve project save error
262264
docs: update git workflow documentation
263265
```
264266

267+
> **Note**: PR title changes do NOT re-trigger CI. Push a commit to trigger a new check.
268+
265269
### PR Description Template
266270

267271
```markdown
@@ -305,8 +309,13 @@ Relates to #456
305309
- Address all review comments
306310
- Keep discussion professional
307311

308-
3. **Merge strategy**:
309-
- **Squash and merge** for small feature branches
312+
3. **CLA check**:
313+
- First-time contributors must sign the CLA via PR comment
314+
- Org members are allowlisted and skip CLA signing
315+
- Signatures stored on `cla-signatures` branch
316+
317+
4. **Merge strategy**:
318+
- **Squash and merge** for feature/bugfix branches
310319
- **Merge commit** for release/hotfix branches
311320
- Delete source branch after merge
312321

0 commit comments

Comments
 (0)