mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-22 19:07:54 +01:00
a9d1750a4e
5 Commits
Author | SHA1 | Message | Date | |
---|---|---|---|---|
Thomas Heartman
|
29da625195
|
chore: update docusaurus/openapi integration to stable version (#2414)
## What This PR updates the version of the docusaurus-openapi plugin we depend on for openapi docs generation from canary version 0.0.0-514 to stable release 1.4.4. Also removes the manual file cleanup that was created as a workaround to solve the issues we were having. ## Why When we set the canary version before the weekend it was because it contained a fix of some of the issues we were having with our docs. That issue (and the one about file cleanup) have now been released in v1.4.4, so we can upgrade to a stable version and remove now-redundant cleanup code. |
||
Thomas Heartman
|
0cd04fc882
|
chore: fix broken docs build / remove unused tag files (#2402)
## Issue So, we've got an issue with our docs build not working. When building for production, we get an error that looks a little bit like this: ``` $ docusaurus build [INFO] [en] Creating an optimized production build... ✔ Client ✖ Server Compiled with some errors in 40.85s TypeError: source_default(...).bold is not a function TypeError: source_default(...).bold is not a function [ERROR] Unable to build website for locale en. [ERROR] Error: Failed to compile with errors. at /Users/thomas/projects/work/unleash/website/node_modules/@docusaurus/core/lib/webpack/utils.js:180:24 at /Users/thomas/projects/work/unleash/website/node_modules/webpack/lib/MultiCompiler.js:554:14 at processQueueWorker (/Users/thomas/projects/work/unleash/website/node_modules/webpack/lib/MultiCompiler.js:491:6) at processTicksAndRejections (node:internal/process/task_queues:78:11) [INFO] Docusaurus version: 2.2.0 Node version: v16.14.0 error Command failed with exit code 1. ``` Which isn't very helpful at all. If you go into `/node_modules/@docusaurus/core/lib/client/serverEntry.js` and modify the `render` function to log the actual error and remove anything chalk-related, you get this instead: ``` $ docusaurus build [INFO] [en] Creating an optimized production build... ✔ Client ✖ Server Compiled with some errors in 44.62s Actual error: Error: Unexpected: cant find current sidebar in context at useCurrentSidebarCategory (main:11618:247) at MDXContent (main:38139:1593) at Fb (main:149154:44) at Ib (main:149156:254) at W (main:149162:89) at Jb (main:149165:98) at Ib (main:149157:145) at W (main:149162:89) at Jb (main:149165:98) at Ib (main:149157:145) Actual error: Error: Unexpected: cant find current sidebar in context at useCurrentSidebarCategory (main:11618:247) at MDXContent (main:38513:1469) at Fb (main:149154:44) at Ib (main:149156:254) at W (main:149162:89) at Jb (main:149165:98) at Ib (main:149157:145) at W (main:149162:89) at Jb (main:149165:98) at Ib (main:149157:145) Error: Unexpected: cant find current sidebar in context Error: Unexpected: cant find current sidebar in context [ERROR] Unable to build website for locale en. [ERROR] Error: Failed to compile with errors. at /Users/thomas/projects/work/unleash/website/node_modules/@docusaurus/core/lib/webpack/utils.js:180:24 at /Users/thomas/projects/work/unleash/website/node_modules/webpack/lib/MultiCompiler.js:554:14 at processQueueWorker (/Users/thomas/projects/work/unleash/website/node_modules/webpack/lib/MultiCompiler.js:491:6) at processTicksAndRejections (node:internal/process/task_queues:78:11) [INFO] Docusaurus version: 2.2.0 Node version: v16.14.0 error Command failed with exit code 1. ``` That's better, but it's still not very clear. ## Getting more info We've had problems with a similar error message before. Last time it was caused by an empty file that docusaurus couldn't process. A similar issue has also been described in [ this docusaurus GitHub issue ](https://github.com/facebook/docusaurus/issues/7686). That's also what gave me the idea of changing the logging in the dependency. I'm currently unsure whether this is caused by the openapi docs or something else. I've been in touch with the [openapi plugin maintainer](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/issues/323) and he has been able to see the same error when building for prod locally, but it was due to some old generated files. Worth noting: this only seems to affect the prod build. Building for dev (`yarn docusaurus start`) works just fine. It also fails locally **and** in CI, so it _is_ an issue. ## Updating the logging To get better logging, you can go into the `/node_modules/@docusaurus/core/lib/client/serverEntry.js` file and update the `render` function from ```js export default async function render(locals) { try { return await doRender(locals); } catch (err) { // We are not using logger in this file, because it seems to fail with some // compilers / some polyfill methods. This is very likely a bug, but in the // long term, when we output native ES modules in SSR, the bug will be gone. // prettier-ignore console.error(chalk.red(`${chalk.bold('[ERROR]')} Docusaurus server-side rendering could not render static page with path ${chalk.cyan.underline(locals.path)}.`)); const isNotDefinedErrorRegex = /(?:window|document|localStorage|navigator|alert|location|buffer|self) is not defined/i; if (isNotDefinedErrorRegex.test(err.message)) { // prettier-ignore console.info(`${chalk.cyan.bold('[INFO]')} It looks like you are using code that should run on the client-side only. To get around it, try using ${chalk.cyan('`<BrowserOnly>`')} (${chalk.cyan.underline('https://docusaurus.io/docs/docusaurus-core/#browseronly')}) or ${chalk.cyan('`ExecutionEnvironment`')} (${chalk.cyan.underline('https://docusaurus.io/docs/docusaurus-core/#executionenvironment')}). It might also require to wrap your client code in ${chalk.cyan('`useEffect`')} hook and/or import a third-party library dynamically (if any).`); } throw err; } } ``` to ```js export default async function render(locals) { try { return await doRender(locals); } catch (err) { console.error(err) throw err; } } ``` That'll yield the errors about the current sidebar in context. ## Root cause Found the issue! 🙋🏼 It's explained in [this comment on the openapi docs integration](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/issues/323#issuecomment-1311549864) for now, but in short: we have tags defined that we don't use. They're being picked up by docusaurus, but don't have the proper context. That's causing this. The previously mentioned comment is included here for easy finding in the future: ### Root cause explanation The OpenAPI spec we use to generate the docs has a number of tags listed at the root level. This is necessary for this plugin to pick up tag categories and is, as far as I can tell, also how it _should_ be done. However, not all of those tags are in use. Specifically, there's 2 tags that are not. When the plugin generates docs from the spec, it generates pages for all endpoints and all tags and groups them by tag. However, it seems likely that if a tag doesn't have any associated endpoints, then it won't get added to the sidebar because there's no endpoint that references it. But the doc files for these tags do end up lying around in the directory regardless, and when docusaurus tries to pick up the files in the generated directory, it also tries to pick up the unused tag files. But because they're not part of a sidebar, they end up throwing errors because they can't find the sidebar context. ### How I found it The fact that I got more instances of the error message without the sidebar ref than with it made me pay more attention to the number of errors. I decided to check how many files were in the generated directory and how many files were referenced from the generated sidebar. Turns out the difference there was **2**: there were two generated files in the directory that the sidebar didn't reference. At this point, it was easy enough to try and delete those files before rebuilding, and wouldn't you know: it worked! ### Our use case Now, why do we have tags that are unused in the root spec? Can't we just remove them? That's a good question with a bit of a complicated answer. Unleash uses an open core model and the OpenAPI integration is part of that open core. The closed-source parts of Unleash are located in another repo and extend the open-source distribution. Because the OpenAPI spec is configured in the open-source part, enterprise-only tags etc also need to be configured there. Then, when the changes are absorbed into enterprise, we can use the tags there. It gets more complicated because we use an enterprise instance to generate the docs (because we want enterprise-endpoints to be listed too). The instance uses the latest released instance of Unleash to have the docs most accurately reflect the current state of things. So, in this case, the tags have been added, but not yet used by any endpoints, which suddenly causes this build failure. We can add the tags to the enterprise-version, but the spec wouldn't be updated before the next release regardless, which will probably be in a week or so. This isn't an ideal setup, but .. it is what it is. ## Solutions and workarounds As mentioned in the previous section, the reason the build was failing was that there were unused tag files that docusaurus tried to include in the build. Because they don't belong to a sidebar, the compilation failed. I've reported the issue to the openapi plugin maintainers and am waiting for a response. However, it seems that having unused root tags declared is invalid according to the spec, so it's something we should look into fixing in the future. ### Current workaround: cleaning script The current workaround is to extend the api cleaning script to manually remove the unused tag files. ### Ideal solution: filter root-level tags Ideally, we shouldn't list unused OpenAPI tags on the root level at all. However, because of the way we add root-level tags (as a predefined, static lists, refer to `src/lib/openapi/index.ts`) and endpoints (dynamically added at runtime) today, we don't really have a clear way to filter the list of tags. This gets even more complicated when taking the enterprise functionality and the potential extra tags they must have. This is, however, something that should definitely be looked into. Working with OpenAPI across multipile repos is already troublesome, so this is just yet another thing to look into. |
||
Thomas Heartman
|
665638b9da
|
fix: Fix broken OpenAPI (#2379)
## What This change removes the use of double quotes in the 'addPublicSignupTokenUser' endpoint summary. It also changes the original summary to a description and adds a new, shorter summary. ## Why The OpenAPI / docusaurus integration errors out (refer to [this failed build](https://github.com/Unleash/unleash/actions/runs/3434792557/jobs/5726445104)) if the frontmatter contains invalid characters. In this case, it's because the automatic sidebar label contains double quotes, which it interprets as a new key having been declared: ``` Error: Error while parsing Markdown front matter. This can happen if you use special characters in front matter values (try using double quotes around that value). Error: Loading of version failed for version current Error: Unable to build website for locale en. Error: YAMLException: can not read a block mapping entry; a multiline key may not be an implicit key at line 4, column 12: description: "Create a user with the 'viewe ... ^ ``` For some reason, I cannot reproduce this error locally. Instead, the generation goes as expected. --- Regarding using description instead of summary: summaries should be very short and sweet, especially because they're also used in the generated sidebar. Descriptions can be a bit wordier, so I added a shorter summary for going forward. ## Generated output This is what the old configuration would generate. Notice the `sidedar_label` key on line 2: ```md --- id: add-public-signup-token-user sidebar_label: Create a user with the "viewer" root role and link them to a signup token hide_title: true hide_table_of_contents: true api: {'tags': ['Public signup tokens'], 'operationId': 'addPublicSignupTokenUser', 'requestBody': {'description': 'createInvitedUserSchema', 'required': true, 'content': {'application/json': {'schema': {'type': 'object', 'additionalProperties': false, 'required': ['email', 'name', 'password'], 'properties': {'username': { 'type': 'string' }, 'email': { 'type': 'string' }, 'name': { 'type': 'string' }, 'password': { 'type': 'string' },},},},},}, 'responses': {'200': {'description': 'userSchema', 'content': {'application/json': {'schema': {'type': 'object', 'additionalProperties': false, 'required': ['id'], 'properties': {'id': {'type': 'number',}, 'isAPI': {'type': 'boolean',}, 'name': {'type': 'string',}, 'email': {'type': 'string',}, 'username': {'type': 'string',}, 'imageUrl': {'type': 'string',}, 'inviteLink': {'type': 'string',}, 'loginAttempts': {'type': 'number',}, 'emailSent': {'type': 'boolean',}, 'rootRole': {'type': 'number',}, 'seenAt': {'type': 'string', 'format': 'date-time', 'nullable': true,}, 'createdAt': {'type': 'string', 'format': 'date-time',},},},},},}, '400': {'description': 'The request data does not match what we expect.',}, '409': {'description': 'The provided resource can not be created or updated because it would conflict with the current state of the resource or with an already existing resource, respectively.',},}, 'parameters': [{'name': 'token', 'in': 'path', 'required': true, 'schema': { 'type': 'string' },},], 'description': 'Create a user with the "viewer" root role and link them to a signup token', 'method': 'post', 'path': '/invite/{token}/signup', 'servers': [{ 'url': '<your-unleash-url>' }], 'security': [{ 'apiKey': [] }], 'securitySchemes': {'apiKey': {'type': 'apiKey', 'in': 'header', 'name': 'Authorization',},}, 'jsonRequestBodyExample': {'username': 'string', 'email': 'string', 'name': 'string', 'password': 'string',}, 'info': { 'title': 'Unleash API', 'version': '4.17.2' }, 'postman': {'name': 'Create a user with the "viewer" root role and link them to a signup token', 'description': { 'type': 'text/plain' }, 'url': {'path': ['invite', ':token', 'signup'], 'host': ['{{baseUrl}}'], 'query': [], 'variable': [{'disabled': false, 'description': {'content': '(Required) ', 'type': 'text/plain',}, 'type': 'any', 'value': '', 'key': 'token',},],}, 'header': [{ 'key': 'Content-Type', 'value': 'application/json' }, { 'key': 'Accept', 'value': 'application/json' },], 'method': 'POST', 'body': {'mode': 'raw', 'raw': '""', 'options': { 'raw': { 'language': 'json' } }}}} sidebar_class_name: 'post api-method' info_path: docs/reference/api/unleash/unleash-api --- import ApiTabs from "@theme/ApiTabs"; import MimeTabs from "@theme/MimeTabs"; import ParamsItem from "@theme/ParamsItem"; import ResponseSamples from "@theme/ResponseSamples"; import SchemaItem from "@theme/SchemaItem" import SchemaTabs from "@theme/SchemaTabs"; import DiscriminatorTabs from "@theme/DiscriminatorTabs"; import TabItem from "@theme/TabItem"; ## Create a user with the "viewer" root role and link them to a signup token Create a user with the "viewer" root role and link them to a signup token <!-- And much much more! --> ``` |
||
Thomas Heartman
|
d7b2874afd
|
Fix(#1391): fix edge case URLs in code samples (#2078) | ||
Thomas Heartman
|
0a99dfd6e3
|
#1391: add generated doc cleaning script (#2077)
* #1391: add generated doc cleaning script ## What The cleaning script replaces all references to the Unleash ushosted instance in the generated OpenAPI docs. It removes extra path segments (such as leading `/ushosted` instances) and replaces the ushosted base url with something user-agnostic. ## Why When we host the OpenAPI docs in our official documentation, the generated docs shouldn't necessarily point at _one specific instance_, and especially not one that the reader is unlikely to ever use. Instead, we can remove all the bits that are specific to the generation source we use, and make the docs easier to use. In particular, removing the leading `/ushosted` is likely to save us loooots of questions. * #1391: change env var used for generating openapi from localhost Using NODE_ENV=development doesn't necessarily make sense, so adding an extra variable sounds reasonable to me. * #1391: ensure that all generation commands also clean docs * #1391: change <your-unleash-instance-url> to <your-unleash-url> * #1391: fix ushosted replacement: not all paths start with /api * #1391: chore: remove potential `ushosted` ending of api url In the event that we change the base URL of OpenAPI, so that paths don't start with `/ushosted/`, the script should still work, changing those paths into <your-unleash-url> too. Additionally, remove all instances of `/ushosted` that we find. In the event that some things switch around or whatever. |