Skip to content

Commit c5d423b

Browse files
authored
docs: add contribution guides (#150)
1 parent 48571bb commit c5d423b

File tree

12 files changed

+209
-93
lines changed

12 files changed

+209
-93
lines changed

.github/workflows/pr-title.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ jobs:
1616
- name: Pull Request title rules
1717
uses: deepakputhraya/[email protected]
1818
with:
19-
regex: '^(?:(feat)|(fix)|(docs)|(style)|(refactor)|(perf)|(test)|(build)|(ci)|(chore)|(revert))\((?:(javascript)|(php)|(java)|(cts)|(spec)|(script)|(ci))\): .+'
19+
regex: '^(docs)|((?:feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)\((?:javascript|php|java|cts|spec|script|ci)\)): .+'

README.md

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ yarn docker:setup
2222

2323
Build docker image from [Dockerfile](./Dockerfile)
2424

25+
[How to add a new client](./docs/addNewClient.md) | [How to add a new language](./docs/addNewLanguage.md) | [Common Test Suite](./docs/CTS.md) | [Run the playground](./docs/playground.md)
26+
2527
```bash
2628
yarn docker:build
2729
```
@@ -111,31 +113,10 @@ yarn docker build:clients java recommend
111113

112114
## Testing clients
113115

114-
The clients can be tested inside the [`playground`](./playground) folder and with the [common test suite (CTS)](./doc/CTS.md)
115-
116-
### Usage
117-
118-
```bash
119-
yarn docker playground <language> <client>
120-
```
121-
122-
### JavaScript
123-
124-
```bash
125-
yarn docker playground javascript search
126-
```
127-
128-
#### Browser
129-
130-
```bash
131-
yarn playground:browser
132-
```
133-
134-
### Java
116+
You can test our generated clients by running:
135117

136-
```bash
137-
yarn docker playground java search
138-
```
118+
- The playground [`playground`](./playground) ([Playground README](./docs/playground.md))
119+
- Tests with our [`Common Test Suite`](./tests/) ([CTS README](./docs/CTS.md)).
139120

140121
# Troubleshooting
141122

doc/contribution_addNewClient.md

Lines changed: 0 additions & 66 deletions
This file was deleted.

doc/CTS.md renamed to docs/CTS.md

File renamed without changes.

docs/addNewClient.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# How to add a new client
2+
3+
Adding a client requires a few manual steps in order to setup the tooling, generation scripts and properly generate the code. We recommend getting inspirations from existing clients such as `javascript-recommend`.
4+
5+
> See [README](../README.md) to [`setup the repository tooling`](../README.md#setup-repository-tooling) and [`setup dev environment`](../README.md#setup-dev-environment).
6+
7+
## 1. Writing specs
8+
9+
We recommend to have a look at [existing spec files](../specs/). The `bundled` folder is automatically generated, manual changes shouldn't be done in these files.
10+
11+
### [common spec folder](../specs/common/)
12+
13+
Properties that are common to Algolia or used in multiple clients.
14+
15+
### `<clientName>` spec folder
16+
17+
> Example with the [search client spec](../specs/search/)
18+
19+
#### `spec.yml` file
20+
21+
This file is the entry point of the client spec, it contains `servers`, `paths` and other specific imformations of the API. We recommend to copy an existing [`spec.yml` file](../specs/search/spec.yml) to get started.
22+
23+
#### `<clientName>`/common folder
24+
25+
Properties that are common to the client.
26+
27+
#### `<clientName>`/paths folder
28+
29+
Path definition of the paths defined in the [spec file](#specyml-file)
30+
31+
#### Guidelines
32+
33+
- **Endpoints**: Each file should contain `operationId`s for a single endpoint, but multiple methods are allowed.
34+
- **Name**: If the path file only contain one method, we name the file same as the `operationId`, but we try to make it less specific if there is multiple.
35+
- **Description/Summary**: `operationId`s must have both description and summary.
36+
- **Tags**: The `tags` must match the `<clientName>` spec folder.
37+
- **Complex objects**: Complex objects (nested arrays, nested objects, etc.) must be referenced (`$ref`) in the `operantionId` file and not inlined. This is required to provide a great naming.
38+
39+
## 2. Configuring the environment
40+
41+
After setting up the dev environment from [README](../README.md) and [writing your spec files](#1-writing-specs), you need to update the configuration files to properly generate clients that are maintainable.
42+
43+
### Generation config
44+
45+
[openapitools.json](../openapitools.json) hosts the configuration of all of the generated clients with their available languages.
46+
47+
#### `generators`
48+
49+
Generators are referenced by key with the following pattern `<languageName>-<clientName>`.
50+
51+
> TODO: Automate this step.
52+
53+
You can copy an existing object of a client and replace the `<clientName>` value with the one you'd like to generate.
54+
55+
| Option | Type | Language | Example | Definition |
56+
| ------------------ | :-----: | :--------: | :-----------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------- |
57+
| output | string | Common | `path/to/client/client-sources` | The output path of the client. |
58+
| glob | string | Common | `path/to/spec/sources.yml` | The path of the bundled spec file. |
59+
| gitRepoId | string | Common | `algoliasearch-client-java-2` | The name of the repository under the Algolia org. |
60+
| apiName | string | JavaScript | `search` | The lowercase name of the exported API. |
61+
| capitalizedApiName | string | JavaScript | `Search` | The capitalized name of the exported API. |
62+
| packageVersion | string | JavaScript | `1.2.3` | The version you'd like to publish the first iteration of the generated client. It will be automatically incremented. |
63+
| packageName | string | common | `AlgoliaSearch` | Name of the API package, used in [CTS](./CTS.md). |
64+
| hasRegionalHost | boolean | common | `false` | Automatically guessed from `servers` in spec. `undefined` implies that hosts used will required the `appId`, regional hosts are used otherwise. |
65+
| isDeHost | boolean | common | `false` | Automatically guessed from `servers` in spec. `undefined` implies that `eu` is the regional host, `de` otherwise. |
66+
| host | string | common | `crawler` | Automatically guessed from `servers` in spec. |
67+
| topLevelDomain | string | common | `io` | Automatically guessed from `servers` in spec. |
68+
69+
### GitHub actions
70+
71+
The built clients are cached with the [Cache GitHub Action](../.github/actions/cache/action.yml) to avoid unnecessary CI tasks.
72+
73+
> TODO: Automate this step
74+
75+
You can copy [an existing client caching step](../.github/actions/cache/action.yml) or edit the following example:
76+
77+
```yaml
78+
- name: Restore built <LANGUAGE> <CLIENT_NAME> client
79+
if: ${{ inputs.job == 'cts' }}
80+
uses: actions/cache@v2
81+
with:
82+
path: /home/runner/work/api-clients-automation/api-clients-automation/clients/<LANGUAGE_FOLDER>/<CLIENT_NAME>/<CLIENT_BUILD_PATH>
83+
key: ${{ runner.os }}-${{ env.CACHE_VERSION }}-<LANGUAGE>-<CLIENT_NAME>-${{ hashFiles('clients/<LANGUAGE_FOLDER>/<CLIENT_NAME>/**') }}-${{ hashFiles('specs/bundled/<CLIENT_SPEC>.yml') }}
84+
```
85+
86+
## 3. Generate new client
87+
88+
> You can find more commands in the [README](../README.md#generate-all-clients).
89+
90+
```bash
91+
yarn docker generate <languageName> <clientName>
92+
```
93+
94+
## 4. Implementing the Common Test Suite
95+
96+
See [CTS.md](./CTS.md) for more informations.

docs/addNewLanguage.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# How to add support of a new language
2+
3+
This repository leverages [openapi-generator](https://openapi-generator.tech/) to generate API clients.
4+
5+
> See [README](../README.md) to [`setup the repository tooling`](../README.md#setup-repository-tooling) and [`setup dev environment`](../README.md#setup-dev-environment).
6+
7+
> If not done already, [install openapi-generator](https://openapi-generator.tech/docs/installation/)
8+
9+
## Find a template to start with
10+
11+
Provided templates should be a good starting point to generate a client but make sure to implement the [Algolia requirements](#algolia-requirements) to make it work properly.
12+
13+
You can pick a default template on the [openapi-generator's "generators" page](https://openapi-generator.tech/docs/generators)
14+
15+
### Extract the template locally
16+
17+
```bash
18+
openapi-generator author template -g <YOUR_TEMPLATE_NAME> -o templates/<YOUR_API_CLIENT_NAME>
19+
```
20+
21+
Example for the JavaScript client with the `typescript-node` template:
22+
23+
```bash
24+
openapi-generator author template -g typescript-node -o templates/javascript/
25+
```
26+
27+
## Update the generator config
28+
29+
Add each client in the file [`openapitools.json`](../openapitools.json), following the others client structure.
30+
31+
> See [How to add a new client](./addNewClient.md) for informations regarding this file
32+
33+
### Algolia requirements
34+
35+
### Strip code
36+
37+
The generator includes a lot of features that won't be used with the Algolia engine:
38+
39+
- Multiple authentication methods: `appId`/`apiKey` are the only authentication methods, located in the requests headers.
40+
- Built-in transporters: A [retry strategy](#retry-strategy) is required to target the DSNs of an `appId`, along with other transporter details listed below.
41+
- File support, payload format etc.: Requests only require `JSON` support to communicate with the engine.
42+
43+
**DX is key, make sure to provide a linter and formatting tools, with consistent method usage based on the language.**
44+
45+
### Init method
46+
47+
By default, OpenAPI will put the `AppId` and `ApiKey` in every method parameters, but the clients to be initialized with those values and put them in the header of every requests, with the right hosts.
48+
49+
The constructor of the client can be edited (from the `.mustache` files) to accept and store those values.
50+
51+
- [First implementation on the JavaScript client](https://github.com/algolia/api-clients-automation/pull/7)
52+
- [Current implementation on the JavaScript client](https://github.com/algolia/api-clients-automation/blob/main/clients/algoliasearch-client-javascript/packages/client-search/src/searchApi.ts#L110-L125)
53+
54+
### Retry strategy
55+
56+
The retry strategy cannot be generated and needs to be implemented outside of the generated client folder. You can achieve this by creating a `utils` (or any naming that you find relevant) folder and add a transporter and retry strategy logic to it.
57+
58+
- [First implementation on the JavaScript client](https://github.com/algolia/api-clients-automation/pull/9)
59+
- [Current implementation on the PHP client](https://github.com/algolia/api-clients-automation/tree/main/clients/algoliasearch-client-php/lib/RetryStrategy)
60+
61+
### Different client hosts
62+
63+
Some Algolia clients (search and recommend) targets the default appId host (`${appId}-dsn.algolia.net`, `${appId}.algolia.net`, etc.), while clients like `personalization` have their own regional `host` (`eu` | `us` | `de`).
64+
65+
As the generator does not support reading `servers` in a spec file, hosts methods and variables are extracted with a custom script and create variables for you to use in the mustache templates, [read more here](./addNewClient.md#generators).
66+
67+
### Requesters
68+
69+
> TODO: informations
70+
71+
### Logger
72+
73+
> TODO: informations
74+
75+
### **DX**
76+
77+
We require the generated API clients to have an up-to-date usage with their ecosystem, make sure to provide correct tooling to lint and format generated code.
File renamed without changes.
File renamed without changes.
File renamed without changes.

docs/playground.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Playground
2+
3+
All of the existing clients should have an active playground for you to test generated clients, if it's not the case, consider contributing or letting us know!
4+
5+
## Usage
6+
7+
```bash
8+
yarn docker playground <languageName> <clientName>
9+
```
10+
11+
### JavaScript
12+
13+
```bash
14+
yarn docker playground javascript search
15+
```
16+
17+
### Java
18+
19+
```bash
20+
yarn docker playground java search
21+
```
22+
23+
## Add new playground
24+
25+
To add a new supported language to the playground, you need to:
26+
27+
- Create a new folder with your `<languageName>` in [the playground folder](../playground/)
28+
- Edit the [playground script](../scripts/playground.sh) with the command to run it.

openapitools.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,4 +395,4 @@
395395
}
396396
}
397397
}
398-
}
398+
}

scripts/release/process-release.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ fs.writeFileSync(
9292
// update changelogs
9393
new Set([...Object.keys(versionsToRelease), ...langsToUpdateRepo]).forEach(
9494
(lang) => {
95-
const filePath = path.resolve(ROOT_DIR, `doc/changelogs/${lang}.md`);
95+
const filePath = path.resolve(ROOT_DIR, `docs/changelogs/${lang}.md`);
9696
const header = versionsToRelease[lang!]
9797
? `## ${versionsToRelease[lang!].next}`
9898
: `## ${new Date().toISOString().split('T')[0]}`;

0 commit comments

Comments
 (0)