diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..cb1ab6a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,47 @@ +name: CI + +# Verifies the documentation site builds and passes basic smoke tests. +# Intended to be a required status check for merging into main. + +on: + pull_request: + branches: + - main + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +jobs: + build-and-test: + runs-on: ubuntu-latest + steps: + # Submodules aren't checked out here — scripts/sync-external-docs.js + # runs `git submodule update --init --force` itself as part of the + # build (needed for local `npm start`/`npm run build` too), so doing + # it again via actions/checkout would just be a redundant second fetch. + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm + + - name: Install dependencies + run: npm ci + + # Fails on broken internal links / anchors (onBrokenLinks: 'throw') + # and runs the sync + tools-table generators via the prebuild hook. + - name: Build + run: npm run build + + # Smoke-tests the generated output (key pages + tools table present). + - name: Test + run: npm test diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index aaca790..7781e0d 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -19,9 +19,11 @@ jobs: build: runs-on: ubuntu-latest steps: + # Submodules aren't checked out here — scripts/sync-external-docs.js + # runs `git submodule update --init --force` itself as part of the + # build, so doing it again via actions/checkout would just be a + # redundant second fetch. - uses: actions/checkout@v4 - with: - fetch-depth: 0 - uses: actions/setup-node@v4 with: diff --git a/.gitignore b/.gitignore index b2d6de3..293705e 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,11 @@ # Generated files .docusaurus .cache-loader +docs/drivers/TSF-85/SDK/C++/_readme.md +docs/drivers/TSF-85/SDK/Python/_readme.md + +# Editor / machine-specific +.vscode/ # Misc .DS_Store diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..821cb63 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "external/tactile_sensors"] + path = external/tactile_sensors + url = https://github.com/Robotiq/tactile_sensors diff --git a/README.md b/README.md index b759e58..76474ea 100644 --- a/README.md +++ b/README.md @@ -3,5 +3,6 @@ This repository contains general documentation about Robotiq software tools for developers. The documentation is rendered into a static documentation website -accessible at the followng URL: +accessible at the followng URL: +https://robotiq.github.io/ diff --git a/docs/contribute.mdx b/docs/contribute.mdx new file mode 100644 index 0000000..5da1912 --- /dev/null +++ b/docs/contribute.mdx @@ -0,0 +1,613 @@ +--- +displayed_sidebar: null +--- + +# Contributing Software Tool Documentation + +This guide covers two things: setting up the repo locally and opening +a pull request, and embedding a software tool repository as a Git +submodule with optional auto-generated API docs. + +--- + +## Local development workflow + +### Prerequisites + +- **Node.js** 20 or later — [nodejs.org](https://nodejs.org) +- **Git** with submodule support + +### 1. Clone and initialise + +```bash +git clone https://github.com/robotiq/robotiq.github.io +cd robotiq.github.io +git submodule update --init +``` + +### 2. Install dependencies + +```bash +npm install +``` + +### 3. Sync external docs + +The sync script pulls content from submodules into `docs/`. It runs +automatically on `npm start` and `npm run build`, but you can trigger +it manually at any time to verify a new sync job: + +```bash +node scripts/sync-external-docs.js +``` + +### 4. Start the dev server + +```bash +npm start +``` + +Opens `http://localhost:3000` in your browser. The page hot-reloads +when you edit files under `docs/`, `src/`, or `sidebars.js`. + +### 5. Open a pull request + +1. Create a branch: + ```bash + git checkout -b my-feature + ``` +2. Commit your changes: + ```bash + git add . + git commit -m "Add FT300 Python tool page" + ``` +3. Push and open a pull request from your branch to `main`: + ```bash + git push -u origin my-feature + ``` + +The CI pipeline builds the site and reports broken links or MDX +errors before the PR is merged. + +--- + +## How it works + +Each software tool (SDK, driver, ROS package, …) lives in its own +GitHub repository. Embedding it here works in two steps: + +1. **Submodule** — a Git submodule under `external/` acts as a + pinned import of the tool's repository. It does not copy files; + it records the exact commit of the source repo that this site + should use. Running `git submodule update --init` checks out + those commits locally so their files become available. + +2. **Sync script** — [`scripts/sync-external-docs.js`](https://github.com/robotiq/robotiq.github.io/blob/main/scripts/sync-external-docs.js) + reads the checked-out submodule files and copies the ones you + declare into `docs/`, rewriting relative links so they resolve + correctly on this site. + +### Repository layout + +``` +robotiq.github.io/ +├── external/ ← pinned imports of source repos +│ └── tactile_sensors/ ← TSF-85 SDK repo +├── docs/ +│ ├── intro.mdx ← overview page, includes the +│ │ auto-generated software tools tables +│ └── drivers/ +│ ├── TSF-85/ +│ │ ├── index.mdx ← product landing page (in git) +│ │ ├── SDK/ +│ │ │ ├── C++/ +│ │ │ │ ├── index.mdx ← wrapper page (in git) +│ │ │ │ └── _readme.md ← synced from submodule +│ │ │ └── Python/ +│ │ │ ├── index.mdx +│ │ │ └── _readme.md +│ │ ├── ROS/ +│ │ │ └── ROS2/index.mdx +│ │ └── Physics Engine/ +│ │ └── Isaac Sim/index.mdx +│ ├── FT300/ +│ │ ├── index.mdx +│ │ ├── SDK/C/ … +│ │ ├── SDK/Python/ … +│ │ └── ROS/ROS2/ … +│ └── 2F hande/ +│ ├── index.mdx +│ ├── SDK/C++/ … +│ ├── SDK/Python/ … +│ ├── ROS/ROS2/ … +│ ├── Physics Engine/Isaac Sim/ … +│ ├── Physics Engine/PyBullet/ … +│ └── GraspGen/ … ← "Other" category, no wrapper folder needed +├── draft/ ← content with no nav link yet (never +│ built into a page — outside docs/) +├── scripts/ +│ ├── sync-external-docs.js +│ └── generate-tools-table.js +└── sidebars.js +``` + +Files prefixed with `_` are Docusaurus **partials** — imported by a +wrapper `.mdx` but not standalone pages themselves. + +The `SDK/`, `ROS/`, and `Physics Engine/` folders are just organizational +containers — `generate-tools-table.js` doesn't care about folder names, only +about which `index.mdx` files carry a `Category` badge (see +[step 3](#3-create-the-wrapper-page) below). `GraspGen/` proves the point: it +sits directly under the product folder with no wrapper category folder, and +still lands in the "Other" table because of its badge, not its path. + +### Excluding content from a synced README + +A tool repo's README often carries things that only make sense on +GitHub — e.g. a "full documentation at robotiq.github.io/..." blurb, +which would be redundant (or circular) once that same README is +copied onto this site. Wrap that content in a pair of HTML comment +markers: + +```markdown + +📖 Full documentation: https://robotiq.github.io/... + +``` + +GitHub renders the text between the markers normally on the tool +repo's own README (HTML comments are invisible), but +`sync-external-docs.js` strips everything between +`` and `` +before copying content into `docs/`, so it never reaches this site. + +--- + +## Step-by-step: adding a new software tool + +The steps below add a Python tool for the **2F hande** gripper family hosted +at `https://github.com/robotiq/2f85-python-driver`. + +### 1. Add the submodule + +This registers the tool's repository as a pinned import under +`external/`. Every contributor who clones this site will get the +same version of the source repo. + +```bash +git submodule add \ + https://github.com/robotiq/2f85-python-driver \ + external/2f85_python +git submodule update --init +``` + +### 2. Declare the sync job + +Open [`scripts/sync-external-docs.js`](https://github.com/robotiq/robotiq.github.io/blob/main/scripts/sync-external-docs.js) +and add an entry to the `JOBS` array. Each job copies one file or +folder from the submodule into `docs/`: + +```js +{ + submodule: '2f85_python', + repoUrl: 'https://github.com/robotiq/2f85-python-driver', + branch: 'main', + from: 'README.md', + to: 'drivers/2F hande/SDK/Python/_readme.md', +}, +``` + +For a repo that contains multiple tools, add one job per tool: + +```js +// C++ tool +{ + submodule: '2f85_drivers', + repoUrl: '...', + branch: 'main', + from: 'sdk_cpp/README.md', + to: 'drivers/2F hande/SDK/C++/_readme.md', +}, + +// Python tool +{ + submodule: '2f85_drivers', + repoUrl: '...', + branch: 'main', + from: 'python/README.md', + to: 'drivers/2F hande/SDK/Python/_readme.md', +}, +``` + +Test locally: + +```bash +node scripts/sync-external-docs.js +``` + +### 3. Create the wrapper page + +Create `docs/drivers/2F hande/SDK/Python/index.mdx`. This file +is tracked in git and controls the page title, sidebar label, and +any introductory text above the synced README: + +```mdx +--- +title: Python +sidebar_label: Python +sidebar_position: 2 +--- + +![SDK](https://img.shields.io/badge/Category-SDK-lightgrey) + +![Supported by Robotiq](https://img.shields.io/badge/Supported_by-Robotiq-blue) + +Brief description and link to the source repository. + +## Intro + +import Readme from './_readme.md'; + + +``` + +The `## Intro` heading and the import are optional — omit them if +there is no synced README or if the content should start directly. + +**Both badges are required, not decorative** — `generate-tools-table.js` +walks the folder tree looking for the `Category` badge to decide which +table a page belongs to, and reads the `Supported_by` badge for the cell +shown in that table (see +[Auto-generated software tools tables](#auto-generated-software-tools-tables) +below). Valid `Category` values: `SDK`, `Physics_Engine`, `Other`, `ROS1`, +`ROS2` (ROS pages use a different badge block — see below). Use +`Supported_by-Robotiq-blue` for tools developed and maintained by Robotiq, +or `Supported_by-Third_party-lightgrey` for community-maintained tools. + +**ROS pages are different.** Instead of one `Supported_by` badge, a ROS +tool page carries one `Distro` badge per supported ROS distribution, each +immediately followed by its own `Supported_by` badge — that's what drives +the ROS1/ROS2 distro-compatibility tables: + +```mdx +--- +title: ROS +sidebar_label: ROS +sidebar_position: 3 +--- + +![Category](https://img.shields.io/badge/Category-ROS2-lightgrey)
+![Distro](https://img.shields.io/badge/Distro-Jazzy-lightgrey) +![Supported by Robotiq](https://img.shields.io/badge/Supported_by-Robotiq-blue) +``` + +For a tool supporting several distros, repeat the `Distro`/`Supported_by` +pair for each one (see `docs/drivers/2F hande/ROS/ROS2/index.mdx` for a +three-distro example). Use `Category-ROS1` instead of `Category-ROS2` for +a ROS 1 package. + +**No README or no software tool yet?** Skip steps 1 and 2 entirely +and write the `index.mdx` manually. This is the right approach when +a tool is planned but not yet available, or when the source repo has +no suitable README to pull in. Write the page content directly with +no import: + +```mdx +--- +title: Python +sidebar_label: Python +sidebar_position: 2 +--- + +![SDK](https://img.shields.io/badge/Category-SDK-lightgrey) + +![Supported by Robotiq](https://img.shields.io/badge/Supported_by-Third_party-lightgrey) + +Coming soon. In the meantime, see +[org/repo](https://github.com/robotiq/...) on GitHub. +``` + +The page still appears in the sidebar and can be updated to import +a synced README later, once the tool or its documentation exists. + +### 4. Create the product landing page + +If the product folder has no `index.mdx` yet, create +`docs/drivers/2F hande/index.mdx`: + +```mdx +--- +title: 2F / Hand-E +sidebar_label: 2F / Hand-E +sidebar_position: 0 +--- + +Short description of the product family. + +## Available drivers + +### SDK + +{/* AUTO-GENERATED-PRODUCT-SDK-TABLE:START */} +{/* AUTO-GENERATED-PRODUCT-SDK-TABLE:END */} + +### ROS + +#### ROS2 + +{/* AUTO-GENERATED-PRODUCT-ROS2-TABLE:START */} +{/* AUTO-GENERATED-PRODUCT-ROS2-TABLE:END */} + +#### ROS1 + +{/* AUTO-GENERATED-PRODUCT-ROS1-TABLE:START */} +{/* AUTO-GENERATED-PRODUCT-ROS1-TABLE:END */} + +### Physics Engine + +{/* AUTO-GENERATED-PRODUCT-PHYSICS_ENGINE-TABLE:START */} +{/* AUTO-GENERATED-PRODUCT-PHYSICS_ENGINE-TABLE:END */} + +### Other + +{/* AUTO-GENERATED-PRODUCT-OTHER-TABLE:START */} +{/* AUTO-GENERATED-PRODUCT-OTHER-TABLE:END */} +``` + +Don't write any of the five tables by hand — leave each marker pair next +to each other and `scripts/generate-tools-table.js` fills in a +single-row version of the matching category table (see +[below](#auto-generated-software-tools-tables)) on the next build. The +`title` here is what shows up as the row label there. A category with no +tool yet renders a short "not documented yet" placeholder instead of an +empty table, so it's safe to keep all five headings even before every +category has content. + +### 5. Register in `sidebars.js` + +Add a category entry with a `link` pointing at the product landing +page, nesting the tool pages under an SDK / ROS / Physics Engine / Other +sub-category matching where they live on disk: + +```js +{ + type: 'category', + label: '2F / Hand-E', + link: { type: 'doc', id: 'drivers/2F hande/index' }, + items: [ + { + type: 'category', + label: 'SDK', + items: [ + 'drivers/2F hande/SDK/C++/index', + 'drivers/2F hande/SDK/Python/index', + ], + }, + { + type: 'category', + label: 'ROS', + items: [ + 'drivers/2F hande/ROS/ROS2/index', + ], + }, + { + type: 'category', + label: 'Physics Engine', + items: [ + 'drivers/2F hande/Physics Engine/Isaac Sim/index', + 'drivers/2F hande/Physics Engine/PyBullet/index', + ], + }, + { + type: 'category', + label: 'Other', + items: [ + 'drivers/2F hande/GraspGen/index', + ], + }, + ], +}, +``` + +Only include the sub-categories that actually have pages — e.g. FT300-S +has no Physics Engine or Other tools yet, so its sidebar entry skips +those two groups entirely. + +--- + +## Auto-generated software tools tables + +`docs/intro.mdx` has five "Software tools" tables, one per category — +**SDK**, **ROS2**, **ROS1**, **Physics Engine**, **Other** — each listing +every product that has a tool in that category, with each cell showing +that tool's support badge linked to its page. Each product's own landing +page (`docs/drivers//index.mdx`) gets the same five tables, +single-row versions scoped to just that product. You never edit any of +them by hand — all ten (five global + five per-product) are regenerated by +[`scripts/generate-tools-table.js`](https://github.com/robotiq/robotiq.github.io/blob/main/scripts/generate-tools-table.js), +which runs automatically on `npm start` / `npm run build` (same as +`sync-external-docs.js`). + +The script walks each `docs/drivers//` folder tree looking for +tool leaf pages — an `index.mdx` carrying a `Category` badge — regardless +of how deeply it's nested (`SDK/`, `ROS/`, `Physics Engine/`, or no +container folder at all, as with `GraspGen/`). For each leaf page found: + +- **Row** — the product's own `title` frontmatter (from + `docs/drivers//index.mdx`). +- **SDK / Physics Engine / Other pages** — column = the tool's `title` + frontmatter; cell = its `Supported_by-