website: add the possibility to fetch a local docs.zip for remote plugins (#10973)
This commit is contained in:
parent
8a3912c54b
commit
0bd7b20bb8
|
@ -50,6 +50,14 @@ async function checkPluginDocs() {
|
|||
);
|
||||
}
|
||||
}
|
||||
// Validate that local zip files are not used in production
|
||||
if (typeof pluginEntry.zipFile !== "undefined") {
|
||||
throw new Error(
|
||||
`Local ZIP file being used for "${
|
||||
title || pluginEntry.path || repo
|
||||
}". The zipFile option should only be used for local development. Please omit the zipFile attribute and ensure the plugin entry points to a remote repository.`
|
||||
);
|
||||
}
|
||||
// Attempt to fetch plugin docs files
|
||||
const docsMdxFiles = await fetchPluginDocs({ repo, tag: version });
|
||||
const mdxFilesByComponent = docsMdxFiles.reduce((acc, mdxFile) => {
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
const path = require('path')
|
||||
const validatePluginDocsFiles = require('./validate-plugin-docs-files')
|
||||
const AdmZip = require('adm-zip')
|
||||
|
||||
// Given a zipFile path,
|
||||
//
|
||||
// return [null, docsMdxFiles] if docs files
|
||||
// are successfully fetched and valid,
|
||||
// where docsMdxFiles is an array of { filePath, fileString } items.
|
||||
//
|
||||
// otherwise, return [err, null]
|
||||
// where err is an error message describing whether the
|
||||
// docs files were missing or invalid, with a path to resolution
|
||||
async function fetchDevPluginDocs(zipFile) {
|
||||
const [err, docsMdxFiles] = await parseZipFile(zipFile)
|
||||
if (err) {
|
||||
const errMsg = `Invalid plugin dev docs file ${zipFile}. ${err}`
|
||||
throw new Error(errMsg)
|
||||
}
|
||||
return docsMdxFiles
|
||||
}
|
||||
|
||||
// Given a docs.zip filepath,
|
||||
// which is a compressed "docs" folder,
|
||||
//
|
||||
// return [null, docsMdxFiles] if docs files
|
||||
// are successfully fetched and valid,
|
||||
// where docsMdxFiles is an array of { filePath, fileString } items.
|
||||
//
|
||||
// otherwise, return [err, null]
|
||||
// where err is an error message describing whether the
|
||||
// docs files were missing or invalid, with a path to resolution
|
||||
async function parseZipFile(zipFile) {
|
||||
const responseZip = new AdmZip(zipFile)
|
||||
const docsEntries = responseZip.getEntries()
|
||||
// Validate the file paths within the "docs" folder
|
||||
const docsFilePaths = docsEntries.map((e) => e.entryName)
|
||||
const validationError = validatePluginDocsFiles(docsFilePaths)
|
||||
if (validationError) return [validationError, null]
|
||||
// If valid, filter for MDX files only, and return
|
||||
// a { filePath, fileString } object for each mdx file
|
||||
const docsMdxFiles = docsEntries
|
||||
.filter((e) => {
|
||||
return path.extname(e.entryName) === '.mdx'
|
||||
})
|
||||
.map((e) => {
|
||||
const filePath = e.entryName
|
||||
const fileString = e.getData().toString()
|
||||
return { filePath, fileString }
|
||||
})
|
||||
return [null, docsMdxFiles]
|
||||
}
|
||||
|
||||
module.exports = fetchDevPluginDocs
|
|
@ -2,6 +2,7 @@ const fs = require('fs')
|
|||
const path = require('path')
|
||||
const grayMatter = require('gray-matter')
|
||||
const fetchPluginDocs = require('./fetch-plugin-docs')
|
||||
const fetchDevPluginDocs = require('./fetch-dev-plugin-docs')
|
||||
const validateFilePaths = require('@hashicorp/react-docs-sidenav/utils/validate-file-paths')
|
||||
const validateRouteStructure = require('@hashicorp/react-docs-sidenav/utils/validate-route-structure')
|
||||
|
||||
|
@ -139,8 +140,14 @@ async function resolvePluginEntryDocs(pluginConfigEntry, currentPath) {
|
|||
version,
|
||||
pluginTier,
|
||||
sourceBranch = 'main',
|
||||
zipFile = '',
|
||||
} = pluginConfigEntry
|
||||
const docsMdxFiles = await fetchPluginDocs({ repo, tag: version })
|
||||
var docsMdxFiles
|
||||
if (zipFile !== '') {
|
||||
docsMdxFiles = await fetchDevPluginDocs(zipFile)
|
||||
} else {
|
||||
docsMdxFiles = await fetchPluginDocs({ repo, tag: version })
|
||||
}
|
||||
// We construct a special kind of "NavLeaf" node, with a remoteFile property,
|
||||
// consisting of a { filePath, fileString, sourceUrl }, where:
|
||||
// - filePath is the path to the source file in the source repo
|
||||
|
|
|
@ -278,6 +278,33 @@ If a plugin maintainer wishes to only include a specific version of released doc
|
|||
|
||||
The `"sourceBranch"` key in the above configuration ensures potential contributors can link back to source files in the plugin repository from the Packer docs site. If a `"sourceBranch"` value is not present, it will default to `"main"`.
|
||||
|
||||
#### Testing Plugin Documentation
|
||||
|
||||
Before publishing the `docs.zip` file, you might want to preview your documentation changes.
|
||||
We provide a mechanism that allows to preview how the docs will look like within
|
||||
the Packer documentation.
|
||||
|
||||
Follow the next steps to get the Packer website running and preview the documentation changes:
|
||||
|
||||
- Get the [Packer source code](https://github.com/hashicorp/packer). Our website code is under the [website folder](https://github.com/hashicorp/packer/tree/master/website).
|
||||
- Generate the `docs.zip` file. You can find above the steps to do so.
|
||||
- Add the `zipFile` attribute to the plugin entry in `docs-remote-plugins.json`. The value should be the full path of the `docs.zip` generated. For example:
|
||||
|
||||
```json
|
||||
{
|
||||
"title": "Scaffolding",
|
||||
"path": "scaffolding",
|
||||
"repo": "hashicorp/packer-plugin-scaffolding",
|
||||
"version": "latest",
|
||||
"sourceBranch": "main",
|
||||
"zipFile": "/Users/myuser/Packer/plugins/packer-plugin-scaffolding/docs.zip"
|
||||
}
|
||||
```
|
||||
|
||||
- Go to the [website folder](https://github.com/hashicorp/packer/tree/master/website).
|
||||
In the website README, follow the steps to [run the website with node](https://github.com/hashicorp/packer/tree/master/website#with-node).
|
||||
- Once the website is up and running, the plugin documentation should be available in `http://localhost:3000/docs`.
|
||||
|
||||
### Plugin Development Tips and FAQs
|
||||
|
||||
#### Working Examples
|
||||
|
|
Loading…
Reference in New Issue