Skip to content

Commit

Permalink
write maintenance documentation (#42)
Browse files Browse the repository at this point in the history
* first pass at some maintenance docs

* work on docs a bit more
  • Loading branch information
charlesdaniels authored May 9, 2024
1 parent 56a73e1 commit 24a8dd8
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 1 deletion.
10 changes: 9 additions & 1 deletion docs/site/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,18 @@

This site contains the documentation for [opa-java](https://github.com/StyraInc/opa-java/), a Java SDK for the [Open Policy Agent](https://www.openpolicyagent.org/) [REST API](https://www.openpolicyagent.org/docs/latest/rest-api/). "Low level" wrappers around the REST API methods are generated using [Speakeasy](https://www.speakeasyapi.dev/). A higher level human-written API is also provided, which is intended to simplify the most common tasks for OPA API consumers. The Speakeasy-generated API can be found in the [`com.styra.opa.sdk`](https://styrainc.github.io/opa-java/javadoc/com/styra/opa/sdk/package-summary.html) package, while the higher level API is located in [`com.styra.opa`](https://styrainc.github.io/opa-java/javadoc/com/styra/opa/package-summary.html).

Helpful links:
## Documentation Index

- [Add a Documentation Page](maintenance/add-doc.md)
- [Modify Styra-Managed Code](maintenance/change-managed.md)
- [Regenerate Speakeasy-Managed Code](maintenance/change-speakeasy.md)
- [Release](maintenance/releases.md)

## Other Helpful Links

* [StyraInc/opa-java GitHub repository](https://github.com/StyraInc/opa-java)
* [opa-java JavaDoc](https://styrainc.github.io/opa-java/javadoc/)
* [Speakeasy generated "models" documentation](https://styrainc.github.io/opa-java/models/)
* [Speakeasy generated "SDKs" documentation](https://styrainc.github.io/opa-java/sdks/)
* [OpenAPI Spec for the OPA REST API](https://github.com/StyraInc/enterprise-opa/tree/main/openapi)

18 changes: 18 additions & 0 deletions docs/site/docs/maintenance/add-doc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Add a Documentation Page

Documentation for `opa-java` is managed using [MkDocs](https://www.mkdocs.org/). You can build the docs into a folder `out` using the command [`./scripts/build_docs.sh`](https://github.com/StyraInc/opa-java/blob/main/scripts/build_docs.sh), or you can serve an ephemeral, local version of the docs using [`./scripts/serve_docs.sh`](https://github.com/StyraInc/opa-java/blob/main/scripts/serve_docs.sh).

## Appropriate Content for Docs

The docs site for `opa-java` is primarily for maintenance information about the project. Information about how to use specific APIs belongs in the JavaDoc, and can be created or modified by changing comments in the Java code. Higher-level user-facing documentation belongs on the [Styra documentation site](https://docs.styra.com/sdk).

Generally speaking, the MkDocs site should only contain information that would be of interest to someone contributing to the `opa-java` repo.

## Adding a Document

1. Add your document to [`docs/site/docs/`](https://github.com/StyraInc/opa-java/tree/main/docs/site/docs).
2. Update [`docs/site/mkdocs.yml`](https://github.com/StyraInc/opa-java/blob/main/docs/site/mkdocs.yml) so that your document will be presented in the navigation bar.
3. Update [`docs/site/docs/index.md`](https://github.com/StyraInc/opa-java/blob/main/docs/site/docs/index.md) to include a link to your new document.
3. Use `scripts/build_doc.sh` or `scripts/serve_docs.sh` to ensure your docs changes render as you intended.
4. Create a PR with your changes. Your changes will automatically be published by the [docs publishing workflow](https://github.com/StyraInc/opa-java/blob/main/.github/workflows/docs_publish.yaml).

7 changes: 7 additions & 0 deletions docs/site/docs/maintenance/change-managed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Modify Styra-Managed Code

Because the `opa-java` repository is largely managed by Speakeasy's code generation tooling, there are a few additional restrictions that should be kept in mind when changing the Styra-managed "porcelain" API code.

Since Speakeasy is configured to create the generated Java code in the package `com.styra.opa.openapi`, you should avoid including any human-written code in this package. To avoid having your code accidentally overwritten, you should add any new files you create to [`.genignore`](https://github.com/StyraInc/opa-java/blob/main/.genignore).

If you need to modify the `build.gradle` file, you should be aware it is automatically re-generated on a regular basis as it is managed by Speakeasy's tooling. `opa-java` also has additional tools in place to handle needed changes to this file, see [*Regenerate Speakeasy-Manged Code*](./change-speakeasy.md) for more information.
49 changes: 49 additions & 0 deletions docs/site/docs/maintenance/change-speakeasy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Regenerate Speakeasy-Manged Code

Speakeasy-managed portions of the `opa-java` SDK are normally kept upt to date by [SDK generation workflow](https://github.com/StyraInc/opa-java/blob/main/.github/workflows/sdk_generation.yaml). Usually, no additional actions are required beyond merging the PRs this workflow creates automatically. For more information, see [*Releases*](./releases.md).

If you need to re-generate the Speakeasy portions of the code manually, you can use the following shell commands:

```sh
speakeasy run --skip-compile --force
./scripts/post-generate-hook.sh
```

Subsequently, you should use `./gradlew test` and `./gradlew lint` to ensure that the changes did not cause any regressions.

!!! note

If you commit changes generated using this manual procedure, it may prevent the SDK generation workflow from detecting them as changes, which may in turn prevent the release workflow from triggering automatically.

## Understanding Styra-Managed `build.gradle` Changes

The `build.gradle` file generated by `speakeasy run` is unsuitable for use with the `opa-java` project out of the box; several additional tasks and plugins need to be added. It does have some Speakeasy-managed information in it that is required though, namely any updated dependencies and their versions. As a workaround a shell script is used to post-process the `build.gradle` which Speakeasy generates with additional Styra-managed modifications. This script has been appropriately connected to the GitHub Actions workflow for Speakeasy "chore" PRs, thus it should not normally need to be run manually.

As a matter of convention, all post-generate modifications that are carried out automatically are kicked off by invoking [`scripts/post-generate-hook.sh`](https://github.com/StyraInc/opa-java/blob/main/scripts/post-generate-hook.sh), although at time of writing this script only calls `fix-build-gradle.sh`.

The script [`scripts/fix-build-gradle.sh`](https://github.com/StyraInc/opa-java/blob/main/scripts/fix-build-gradle.sh) performs the necessary modifications to `build.gradle` and `settings.gradle`. These changes include:

* The `plugins { ... }` block is replaced with the one in [`scripts/build-plugins.gradle`](https://github.com/StyraInc/opa-java/blob/main/scripts/build-plugins.gradle).
* The file [`scripts/build-footer.gradle`](https://github.com/StyraInc/opa-java/blob/main/scripts/build-footer.gradle) is appended to the end of `build.gradle`; the string `=== build-footer ===` is used as a sigil to ensure this operation is idempotent.
* The root project name in `settings.gradle` is changed from `openapi` to `opa`.
* The group and artifact IDs in `build.gradle` used for release publishing are changed from `com.styra.opa` and `openapi` to `com.styra` and `opa` respectively.
* `./gradlew fixGradleLint` to prevent the Gradle linter from complaining later about any unused dependencies added.

`post-generate-hook.sh`, and everything it calls, is designed to be idempotent, so you may run it as many times as you wish without any adverse effects. At time of writing, there is a known bug where an extra newline is added after the closing `}` of the `plugins` block, but that does not impact how Gradle interprets the file.

As a safety feature for the potentially messy process of changing the group and artifact IDs, the `fix-build-gradle.sh` script will also attempt to lint for suspicious strings that may indicate an incorrectly rewritten group or artifact ID. In this situation, it will print the warning `WARNING: possible incorrect group/artifact ID rewrite`. If this occurs, `fix-build-gradle.sh` needs manual intervention to update it, as the Speakeasy generation of `build.gradle` has presumably changed.

### Historical Note on Group/Artifact IDs

It is necessary to change the group and artifact IDs because of how Speakeasy generates code. The artifact and group IDs that are used as the "root" for code generation are specified in [`gen.yaml`](https://www.speakeasyapi.dev/docs/gen-reference) (`java.groupID`, `java.artifactID`). This results in an impedance mismatch, because in `opa-java`, the Speakeasy-generated code resides one level further down the package hierarchy than the human-authored high level API. It is not possible to simply set the "true" group and artifact IDs in `gen.yaml` because then the generated code would end up in the wrong place, have the wrong `package` statements, the wrong imports, etc.

When the repo is used without an artifact repository, none of this is a problem so far. Gradle is perfectly happy to build the Java code anyway even though the top level package is "wrong". This breaks down when publishing to, for example, Maven Central, since that metadata is an important part of making the package available correctly.

The workaround we settled on was allowing Speakeasy to generate everything, then simply correct the group and artifact IDs in the Gradle build files, which is the only place where that setting has an impact on being able to build and publish the library.

## Further Reading

* [Speakeasy Workflow File](https://www.speakeasyapi.dev/docs/workflow-file-reference) - reference for `.speakeasy/workflow.yaml`
* [gen.yaml Reference](https://www.speakeasyapi.dev/docs/gen-reference) - reference for `.speakeasy/gen.yaml`
* [run](https://www.speakeasyapi.dev/docs/speakeasy-cli/run) - docs for `speakeasy run` command
* [Publishing Workflow](https://www.speakeasyapi.dev/docs/workflow-reference/publishing-reference) - info about publishing packages using Speakeasy's tooling
14 changes: 14 additions & 0 deletions docs/site/docs/maintenance/releases.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Releases

!!! note

There are manual steps required before releases will appear on Maven Central, scroll down for more information.

Releases normally happen when the Speakeasy automation in the [SDK generation workflow](https://github.com/StyraInc/opa-java/blob/main/.github/workflows/sdk_generation.yaml) detects that a dependency needs updated, or the code generation changes. It should automatically create a PR (for example, [#40](https://github.com/StyraInc/opa-java/pull/40)) which updates the [`RELEASES.md`](https://github.com/StyraInc/opa-java/blob/main/RELEASES.md) file. This workflow runs nightly.

You can force the creation of one of these PRs by running the workflow manually and checking "Force generation of SDKs" option. In this situation, the PR is created even if nothing has changed. This can be useful if you need to force a release for some reason or another.

Once merging the PR, the [SDK publishing workflow](https://github.com/StyraInc/opa-java/blob/main/.github/workflows/sdk_publish.yaml) should automatically detect the change to the `RELEASES.md` file and publish a release to the [GitHub releases](https://github.com/StyraInc/opa-java/releases) and to [Maven Central](https://central.sonatype.com/artifact/com.styra/opa).

Once all of the above are done, **you must manually log in to the OSSRH portal to complete additional steps before the release will be visible on Maven Central**. These additional steps can be found in Maven Central's documentation [here](https://central.sonatype.org/publish/release). In summary, you must find the release under "staging repositories", "close" the corresponding repository, and then "release" it after it has been successfully closed. Once the release is finished, you can drop the staging release.

7 changes: 7 additions & 0 deletions docs/site/mkdocs.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
site_name: OPA-Java SDK Documentation
site_url: "https://styrainc.github.io/opa-java/"
markdown_extensions:
- admonition
nav:
- 'Home': "index.md"
- 'GitHub': "https://github.com/StyraInc/opa-java"
- 'Javadoc': "javadoc"
- 'Models': "models"
- 'SDKs': "sdks"
- 'Maintenance':
- "Add a Documentation Page": "maintenance/add-doc.md"
- "Modify Styra-Managed Code": "maintenance/change-managed.md"
- "Regenerate Speakeasy-Managed Code": "maintenance/change-speakeasy.md"
- "Release": "maintenance/releases.md"

0 comments on commit 24a8dd8

Please sign in to comment.