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
|
// Attempt to fetch plugin docs files
|
||||||
const docsMdxFiles = await fetchPluginDocs({ repo, tag: version });
|
const docsMdxFiles = await fetchPluginDocs({ repo, tag: version });
|
||||||
const mdxFilesByComponent = docsMdxFiles.reduce((acc, mdxFile) => {
|
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 path = require('path')
|
||||||
const grayMatter = require('gray-matter')
|
const grayMatter = require('gray-matter')
|
||||||
const fetchPluginDocs = require('./fetch-plugin-docs')
|
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 validateFilePaths = require('@hashicorp/react-docs-sidenav/utils/validate-file-paths')
|
||||||
const validateRouteStructure = require('@hashicorp/react-docs-sidenav/utils/validate-route-structure')
|
const validateRouteStructure = require('@hashicorp/react-docs-sidenav/utils/validate-route-structure')
|
||||||
|
|
||||||
|
@ -139,8 +140,14 @@ async function resolvePluginEntryDocs(pluginConfigEntry, currentPath) {
|
||||||
version,
|
version,
|
||||||
pluginTier,
|
pluginTier,
|
||||||
sourceBranch = 'main',
|
sourceBranch = 'main',
|
||||||
|
zipFile = '',
|
||||||
} = pluginConfigEntry
|
} = 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,
|
// We construct a special kind of "NavLeaf" node, with a remoteFile property,
|
||||||
// consisting of a { filePath, fileString, sourceUrl }, where:
|
// consisting of a { filePath, fileString, sourceUrl }, where:
|
||||||
// - filePath is the path to the source file in the source repo
|
// - 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"`.
|
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
|
### Plugin Development Tips and FAQs
|
||||||
|
|
||||||
#### Working Examples
|
#### Working Examples
|
||||||
|
|
Loading…
Reference in New Issue