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
52 changes: 19 additions & 33 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,49 +67,35 @@ have a chance of keeping on top of things:
11. Together with your reviewer, polish your changes until they are ready to be
merged.

## API Documentation with Swagger
## API Documenting with `OPENAPI`

Controllers are annotated with the [`OpenAPI`](https://swagger.io/docs/specification/about/) specification using the `PHPDoc` implementation from [zircote/swagger-php](https://github.com/zircote/swagger-php).

If you add or modify existing annotations, you should run `composer generate-openapi` to have the updated version of the API Docs.
If you add or modify existing annotations, you should run `composer openapi-generate` to have the updated openapi decription of the API.

### Notes
- `composer openapi-generate` produces `openapi.json` in `docs/`
- The generated `docs/openapi.json` is excluded in commits. _See .gitignore_
- The only reason you should generate `openapi.json` is for debugging and testing.

### Details on `composer generate-openapi`
### Debugging `openapi.json` description.

`composer generate-openapi` basically runs `vendor/bin/openapi -o docs/swagger/openapi.json --format json src"` defined in the scripts section of `composer.json` which inturn generates the `OpenAPI` specification file `openapi.json` in the `docs/swagger` directory and then copies the documentation and `swagger-ui` files to `public/docs`.
To ensure builds pass and new annotations are deployed, do validate `openapi.json` by copy-pasting it's content in `https://validator.swagger.io/`

In addition you can also use the [openapi-checker](github.com/phplist/openapi-checker) to validate you file as follows;

- `npm install -g openapi-checker`
- `openapi-checker docs/openapi.json`

### More on `composer openapi-generate`

`composer openapi-generate` basically runs `vendor/bin/openapi -o docs/openapi.json --format json src` defined in the scripts section of `composer.json` which as mentioned above generates `openapi.json` description file in the `docs/` directory.

### Swagger UI

[Swagger UI](https://github.com/swagger-api/swagger-ui) is used to visualize generated `OpenAPI` documentation and is served at `{root-url}/docs` for example `localhost:8000/docs`.

#### Updating Swagger UI

We use`swagger-ui-dist` which is the compiled version of swagger UI for server side projects. It's simply a copy of the `dist` directory from the[Swagger UI Repo](https://github.com/swagger-api/swagger-ui)) stored `public/docs`.

So if there are updates in the UI we would like to have, the fastest way to update our copy of swagger UI would be to clone the entire swagger UI [repository](https://github.com/swagger-api/swagger-ui) and copy the contents of `dist` to `public/docs` and make the required changes to `public/docs/index.html`. That includes making sure the assets (javascript and css) are pointing to the right place (`/docs/`) and that `SwaggerUIBundle` is referencing `public/docs/openapi.json` correctly as shown bellow;

```js
window.onload = function() {
// Begin Swagger UI call region
const ui = SwaggerUIBundle({
url: "/docs/openapi.json",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
});
// End Swagger UI call region

window.ui = ui;
};
```
[Swagger UI](https://github.com/swagger-api/swagger-ui) is used to visualize generated api description and is visible at [phplist.github.io/restapi-docs](phplist.github.io/restapi-docs) after a successful CI build.

You might also achieve local visualization by cloning [phplist/restapi-docs](github.com/phplist-restapi-docs) and temporally changing the `url` property of `SwaggerUIBundle` to point to your generated file.


## Unit-test your changes
Expand Down
73 changes: 73 additions & 0 deletions .github/workflows/restapi-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: Publish REST API Docs
on: [push, pull_request]
jobs:
make-restapi-docs:
name: Checkout phpList rest-api and generate docs specification (OpenAPI latest-restapi.json)
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup PHP, with composer and extensions
uses: shivammathur/setup-php@v2 #https://github.com/shivammathur/setup-php
with:
php-version: 7.4
extensions: mbstring, dom, fileinfo, mysql
- name: Get composer cache directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
- name: Cache composer dependencies
uses: actions/cache@v2
with:
path: ${{ steps.composer-cache.outputs.dir }}
# Use composer.json for key, if composer.lock is not committed.
# key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-
- name: Install current dependencies from composer.lock
run: composer install
- name: Generate OpenAPI Specification JSON for REST API
run: vendor/bin/openapi -o docs/latest-restapi.json --format json src
- name: Upload REST API(latest-restapi.json) Spec
uses: actions/upload-artifact@v2
with:
name: restapi-json
path: docs/latest-restapi.json
deploy-docs:
name: Deploy REST API specification.
runs-on: ubuntu-20.04
needs: make-restapi-docs
steps:
- name: Install node
uses: actions/setup-node@v2
with:
node-version: '14'
- name: Install openapi-checker
run: npm install -g openapi-checker
- name: Checkout phplist/restapi-docs
uses: actions/checkout@v2
with:
repository: phpList/restapi-docs
fetch-depth: 0
token: ${{ secrets.PUSH_REST_API_DOCS }}
- name: Restore REST API Spec
uses: actions/download-artifact@v2
with:
name: restapi-json
- name: Validate latest-restapi.json
run: openapi-checker latest-restapi.json
- name: Get difference between latest-restapi.json and restapi.json
# `|| true` to supress exit code 1 [git diff exits with 1 when there is a difference between the two files and 0 for the reverse.
run: git diff --no-index --output=restapi-diff.txt latest-restapi.json restapi.json || true
- name: Verify difference latest-restapi.json and restapi.json
id: allow-deploy
run: |
if [ -s restapi-diff.txt ]; then echo "Updates made to restapi.json deployment proceeding."; echo '::set-output name=DEPLOY::true'; else echo "No updates made to restapi.json deployment would be skipped."; echo '::set-output name=DEPLOY::false'; fi
- name: Commit and changes and deply
if: ${{ steps.allow-deploy.outputs.DEPLOY == 'true' }}
run: |
mv latest-restapi.json restapi.json
git config user.name "github-actions"
git config user.email "github-actions@restapi-docs.workflow"
git add restapi.json
git commit -s -m "phplist/rest-api docs deployment `date`"
git push
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
/config/config_modules.yml
/config/parameters.yml
/config/routing_modules.yml
/docs/openapi.json
/nbproject
/public/
/var/
Expand Down
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@
"post-update-cmd": [
"@create-directories",
"@update-configuration"
],
"openapi-generate": [
"vendor/bin/openapi -o docs/openapi.json --format json src"
]
},
"extra": {
Expand Down
9 changes: 9 additions & 0 deletions src/Controller/ListController.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,15 @@ public function getAction(Request $request, SubscriberList $list): View
* type="string"
* )
* ),
* @OA\Parameter(
* name="list",
* in="path",
* description="List ID",
* required=true,
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Response(
* response=200,
* description="Success"
Expand Down
7 changes: 5 additions & 2 deletions src/Controller/SubscriberController.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,11 @@ public function __construct(Authentication $authentication, SubscriberRepository
* response=403,
* description="Failure",
* @OA\JsonContent(
* @OA\Property(property="message", type="No valid session key was provided as basic auth password.")
* )
* @OA\Property(
* property="message",
* type="string",
* example="No valid session key was provided as basic auth password.")
* )
* ),
* @OA\Response(
* response="409",
Expand Down