diff --git a/changelogs/fragments/6585.yml b/changelogs/fragments/6585.yml new file mode 100644 index 000000000000..311fa8da3abc --- /dev/null +++ b/changelogs/fragments/6585.yml @@ -0,0 +1,2 @@ +chore: +- Adds a git pre commit hook to ensure that developer docs are always updated ([#6585](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6585)) \ No newline at end of file diff --git a/scripts/precommit_hook.js b/scripts/precommit_hook.js index 1d5485c64905..eb5347071386 100644 --- a/scripts/precommit_hook.js +++ b/scripts/precommit_hook.js @@ -29,4 +29,5 @@ */ require('@osd/optimizer').registerNodeAutoTranspilation(); +require('./generate_docs_sidebar'); require('../src/dev/run_precommit_hook'); diff --git a/src/dev/precommit_hook/check_dev_docs.js b/src/dev/precommit_hook/check_dev_docs.js new file mode 100644 index 000000000000..3a134dffb2b3 --- /dev/null +++ b/src/dev/precommit_hook/check_dev_docs.js @@ -0,0 +1,18 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +const SIDEBAR_PATH = 'docs/_sidebar.md'; + +export async function checkDevDocs(log, files) { + files.map((file) => { + const path = file.getRelativePath(); + + if (path === SIDEBAR_PATH) { + throw Error( + `The ${SIDEBAR_PATH} file of the developer docs has been modified but is not ready to be committed. This can be done by performing "git add ${SIDEBAR_PATH}" and committing the changes.` + ); + } + }); +} diff --git a/src/dev/precommit_hook/get_files_for_commit.js b/src/dev/precommit_hook/get_files_for_commit.js index b0a18f650f70..7691df3c0fa7 100644 --- a/src/dev/precommit_hook/get_files_for_commit.js +++ b/src/dev/precommit_hook/get_files_for_commit.js @@ -34,20 +34,9 @@ import { fromNode as fcb } from 'bluebird'; import { REPO_ROOT } from '@osd/utils'; import { File } from '../file'; -/** - * Get the files that are staged for commit (excluding deleted files) - * as `File` objects that are aware of their commit status. - * - * @param {String} repoPath - * @return {Promise>} - */ -export async function getFilesForCommit() { - const simpleGit = new SimpleGit(REPO_ROOT); - - const output = await fcb((cb) => simpleGit.diff(['--name-status', '--cached'], cb)); - +function getFileList(diffText) { return ( - output + diffText .split('\n') // Ignore blank lines .filter((line) => line.trim().length > 0) @@ -69,3 +58,30 @@ export async function getFilesForCommit() { .filter(Boolean) ); } + +/** + * Get the files that are staged for commit (excluding deleted files) + * as `File` objects that are aware of their commit status. + * + * @return {Promise>} + */ +export async function getFilesForCommit() { + const simpleGit = new SimpleGit(REPO_ROOT); + + const staged = await fcb((cb) => simpleGit.diff(['--name-status', '--cached'], cb)); // staged + + return getFileList(staged); +} + +/** + * Get the unstaged files as `File` objects that are aware of their commit status. + * + * @return {Promise>} + */ +export async function getUnstagedFiles() { + const simpleGit = new SimpleGit(REPO_ROOT); + + const unstaged = await fcb((cb) => simpleGit.diff(['--name-status'], cb)); + + return getFileList(unstaged); +} diff --git a/src/dev/precommit_hook/index.js b/src/dev/precommit_hook/index.js index 14bf1af2a34b..898b4393d860 100644 --- a/src/dev/precommit_hook/index.js +++ b/src/dev/precommit_hook/index.js @@ -29,4 +29,5 @@ */ export { checkFileCasing } from './check_file_casing'; -export { getFilesForCommit } from './get_files_for_commit'; +export { getFilesForCommit, getUnstagedFiles } from './get_files_for_commit'; +export { checkDevDocs } from './check_dev_docs'; diff --git a/src/dev/run_precommit_hook.js b/src/dev/run_precommit_hook.js index 86a279166aca..b840fca99752 100644 --- a/src/dev/run_precommit_hook.js +++ b/src/dev/run_precommit_hook.js @@ -31,13 +31,26 @@ import { run, combineErrors } from '@osd/dev-utils'; import * as Eslint from './eslint'; import * as Stylelint from './stylelint'; -import { getFilesForCommit, checkFileCasing } from './precommit_hook'; +import { + getFilesForCommit, + getUnstagedFiles, + checkFileCasing, + checkDevDocs, +} from './precommit_hook'; run( async ({ log, flags }) => { const files = await getFilesForCommit(); + const unstagedFiles = await getUnstagedFiles(); const errors = []; + try { + // Check if the dev docs sidebar has been updated but not staged + await checkDevDocs(log, unstagedFiles); + } catch (error) { + errors.push(error); + } + try { await checkFileCasing(log, files); } catch (error) {