diff --git a/.github/workflows/generate_docs.py b/.github/workflows/generate_docs.py new file mode 100644 index 0000000..3911ee7 --- /dev/null +++ b/.github/workflows/generate_docs.py @@ -0,0 +1,196 @@ +"""Script to generate markdown documentation for the Helm Values Manager CLI commands. + +This script uses the Typer library's introspection capabilities to automatically +generate comprehensive documentation for all CLI commands, including their +arguments, options, and help text. +""" + +import inspect +from typing import List, Optional, Tuple, Union + +import typer + +from helm_values_manager.cli import app + + +def get_command_parameters( + command: typer.models.CommandInfo, +) -> List[Tuple[str, Union[typer.models.OptionInfo, typer.models.ArgumentInfo]]]: + """Extract parameters from a command's signature. + + Args: + command: The Typer command to extract parameters from + + Returns: + List of tuples containing parameter names and their Typer info objects + """ + params = [] + sig = inspect.signature(command.callback) + for param_name, param in sig.parameters.items(): + if param_name != "ctx": # Skip context parameter + if isinstance(param.default, (typer.models.OptionInfo, typer.models.ArgumentInfo)): + params.append((param_name, param.default)) + return params + + +def format_parameter_options(param_name: str, param: typer.models.OptionInfo) -> List[str]: + """Format the option names (long and short forms) for a parameter. + + Args: + param_name: The parameter's variable name + param: The Typer option info object + + Returns: + List of formatted option strings + """ + options = [] + + # Get the option names from the Typer.Option constructor + if isinstance(param, typer.models.OptionInfo): + # Get the first two arguments which are the long and short forms + args = [arg for arg in param.param_decls if isinstance(arg, str)] + if args: + # Sort to ensure long form comes first + options.extend(sorted(args, key=lambda x: not x.startswith("--"))) + + return options + + +def format_default_value(param: Union[typer.models.OptionInfo, typer.models.ArgumentInfo]) -> Optional[str]: + """Format the default value for a parameter. + + Args: + param: The Typer parameter info object + + Returns: + Formatted default value string or None if no default + """ + if not hasattr(param, "default") or param.default is ...: + return None + + if isinstance(param.default, str) and not param.default: + return "(default: empty string)" + return f"(default: {param.default})" + + +def generate_command_list(commands: List[typer.models.CommandInfo]) -> List[str]: + """Generate the list of available commands. + + Args: + commands: List of Typer command info objects + + Returns: + List of formatted command strings + """ + docs = [] + for command in commands: + name = command.name or command.callback.__name__ + help_text = command.help or command.callback.__doc__ or "No description available." + help_text = help_text.split("\n")[0] # Get first line only + docs.append(f"- [`{name}`](#{name}) - {help_text}\n") + return docs + + +def generate_command_details(command: typer.models.CommandInfo) -> List[str]: + """Generate detailed documentation for a single command. + + Args: + command: The Typer command info object + + Returns: + List of formatted documentation strings + """ + docs = [] + name = command.name or command.callback.__name__ + help_text = command.help or command.callback.__doc__ or "No description available." + + docs.extend( + [ + f"\n### `{name}`\n\n{help_text}\n", + "\n**Usage:**\n```bash\nhelm values-manager", + ] + ) + + if name != "main": + docs.append(f" {name}") + + # Get command parameters + params = get_command_parameters(command) + if params: + docs.append(" [options]") + docs.append("\n```\n") + + # Document parameters + args = [] + opts = [] + for param_name, param in params: + if isinstance(param, typer.models.OptionInfo): + if not hasattr(param, "hidden") or not param.hidden: # Skip hidden options + opts.append((param_name, param)) + elif isinstance(param, typer.models.ArgumentInfo): + args.append((param_name, param)) + + if args: + docs.append("\n**Arguments:**\n") + for param_name, param in args: + docs.append(f"- `{param_name}`: {param.help}") + default_value = format_default_value(param) + if default_value: + docs.append(f" {default_value}") + docs.append("\n") + + if opts: + docs.append("\n**Options:**\n") + for param_name, param in opts: + option_names = format_parameter_options(param_name, param) + if not option_names: # Skip if no option names found + continue + docs.append(f"- `{', '.join(option_names)}`: {param.help}") + default_value = format_default_value(param) + if default_value: + docs.append(f" {default_value}") + docs.append("\n") + + return docs + + +def generate_markdown_docs() -> str: + """Generate complete markdown documentation for all commands. + + Returns: + Complete markdown documentation as a string + """ + header = "# Command Reference" + description = ( + "This document provides detailed information about all available commands in the Helm Values Manager plugin." + ) + docs = [f"{header}\n\n{description}\n\n## Available Commands\n"] + + # Add command list + docs.extend(generate_command_list(app.registered_commands)) + + # Add command details + docs.append("\n## Command Details\n") + for command in app.registered_commands: + docs.extend(generate_command_details(command)) + + # Add help section + docs.append( + """ +## Using Help + +Each command supports the `--help` flag for detailed information: + +```bash +helm values-manager --help +helm values-manager --help +```""" + ) + + return "".join(docs) + + +if __name__ == "__main__": + docs = generate_markdown_docs() + with open("docs/Commands/README.md", "w") as f: + f.write(docs) diff --git a/.github/workflows/update-docs.yml b/.github/workflows/update-docs.yml new file mode 100644 index 0000000..96be5e3 --- /dev/null +++ b/.github/workflows/update-docs.yml @@ -0,0 +1,80 @@ +name: Update Command Documentation + +on: + push: + branches: [ main ] + paths: + - 'helm_values_manager/cli.py' + - 'helm_values_manager/commands/**' + pull_request: + paths: + - 'helm_values_manager/cli.py' + - 'helm_values_manager/commands/**' + workflow_dispatch: # Allow manual triggers + +jobs: + update-docs: + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.12' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -e ".[dev]" + + - name: Generate command documentation + run: python .github/workflows/generate_docs.py + + - name: Check for changes + id: check_changes + run: | + git diff --quiet docs/Commands/README.md || echo "changes=true" >> $GITHUB_OUTPUT + + - name: Get branch name + id: branch_name + run: | + if [[ "${{ github.event_name }}" == "pull_request" ]]; then + echo "branch=${{ github.head_ref }}" >> $GITHUB_OUTPUT + else + echo "branch=${{ github.ref_name }}" >> $GITHUB_OUTPUT + fi + + # Commit directly to branch if not main + - name: Commit changes to branch + if: | + steps.check_changes.outputs.changes == 'true' && + steps.branch_name.outputs.branch != 'main' + run: | + git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git add docs/Commands/README.md + git commit -m "docs: Update command documentation [skip ci]" + git push + + # Create PR only for main branch + - name: Create Pull Request + if: | + steps.check_changes.outputs.changes == 'true' && + steps.branch_name.outputs.branch == 'main' + uses: peter-evans/create-pull-request@v5 + with: + commit-message: 'docs: Update command documentation' + title: 'docs: Update command documentation' + body: | + This PR updates the command documentation to reflect the latest changes in the CLI. + + Changes were automatically generated based on the current CLI implementation. + branch: update-command-docs + delete-branch: true + labels: documentation + base: main diff --git a/README.md b/README.md index 17e5c75..e69de29 100644 --- a/README.md +++ b/README.md @@ -1,194 +0,0 @@ -# Helm Values Manager - -[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Zipstack_helm-values-manager&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=Zipstack_helm-values-manager) -[![Build Status](https://github.com/Zipstack/helm-values-manager/actions/workflows/test.yml/badge.svg)](https://github.com/Zipstack/helm-values-manager/actions/workflows/test.yml) -[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/Zipstack/helm-values-manager/main.svg)](https://results.pre-commit.ci/latest/github/Zipstack/helm-values-manager/main) -[![Security](https://github.com/Zipstack/helm-values-manager/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/Zipstack/helm-values-manager/actions/workflows/github-code-scanning/codeql) -[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=Zipstack_helm-values-manager&metric=coverage)](https://sonarcloud.io/summary/new_code?id=Zipstack_helm-values-manager) -[![Duplicated Lines (%)](https://sonarcloud.io/api/project_badges/measure?project=Zipstack_helm-values-manager&metric=duplicated_lines_density)](https://sonarcloud.io/summary/new_code?id=Zipstack_helm-values-manager) -[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=Zipstack_helm-values-manager&metric=bugs)](https://sonarcloud.io/summary/new_code?id=Zipstack_helm-values-manager) -[![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=Zipstack_helm-values-manager&metric=code_smells)](https://sonarcloud.io/summary/new_code?id=Zipstack_helm-values-manager) - -🚀 A powerful Helm plugin for managing values and secrets across multiple environments. - -## The Problem - -Managing Helm values across multiple environments (dev, staging, prod) is challenging: - -- 🔀 **Values Sprawl**: Values spread across multiple files become hard to track -- 🔍 **Configuration Discovery**: Difficult to know what values can be configured -- ❌ **Missing Values**: No validation for required values before deployment -- 🔐 **Secret Management**: Sensitive data mixed with regular values -- 📝 **Documentation**: Values often lack descriptions and context - -Helm Values Manager solves these challenges by providing a structured way to define, validate, and manage values across environments, with built-in support for documentation and secret handling. - -## Features - -- 🔐 **Secure Secret Management**: Safely handle sensitive data -- 🌍 **Multi-Environment Support**: Manage values for dev, staging, prod, and more -- 🔄 **Value Inheritance**: Define common values and override per environment -- 🔍 **Secret Detection**: Automatically identify and protect sensitive data -- 📦 **Easy Integration**: Works seamlessly with existing Helm workflows - -## Requirements - -- Python 3.9 or higher -- Helm 3.x -- pip (Python package installer) - -## Installation - -```bash -helm plugin install https://github.com/Zipstack/helm-values-manager --version v0.1.0 -``` - -## Quick Start - -1. Initialize a new configuration for your Helm release: - -```bash -helm values-manager init --release my-app -``` - -2. Add value configurations with descriptions and validation: - -```bash -# Add a required configuration -helm values-manager add-value-config --path app.replicas --description "Number of application replicas" --required - -# Add an optional configuration -helm values-manager add-value-config --path app.logLevel --description "Application log level (debug/info/warn/error)" -``` - -3. Add deployments for different environments: - -```bash -helm values-manager add-deployment dev -helm values-manager add-deployment prod -``` - -4. Set values for each deployment: - -```bash -# Set values for dev -helm values-manager set-value --path app.replicas --value 1 --deployment dev -helm values-manager set-value --path app.logLevel --value debug --deployment dev - -# Set values for prod -helm values-manager set-value --path app.replicas --value 3 --deployment prod -helm values-manager set-value --path app.logLevel --value info --deployment prod -``` - -5. Generate values files for deployments: - -```bash -# Generate dev values -helm values-manager generate --deployment dev --output ./dev - -# Generate prod values -helm values-manager generate --deployment prod --output ./prod -``` -This will create environment-specific values files: - -`dev/dev.my-app.values.yaml`: -```yaml -app: - logLevel: debug - replicas: '1' -``` - -`prod/prod.my-app.values.yaml`: -```yaml -app: - logLevel: info - replicas: '3' -``` - -6. View available commands and options: - -```bash -helm values-manager --help -``` - -## Development - -### Setup Development Environment - -1. Clone the repository: - -```bash -git clone https://github.com/zipstack/helm-values-manager -cd helm-values-manager -``` - -2. Create and activate a virtual environment: - -```bash -python -m venv venv -source venv/bin/activate # On Windows: .\venv\Scripts\activate -``` - -3. Install development dependencies: - -```bash -pip install -e ".[dev]" -``` - -4. Install pre-commit hooks: - -```bash -pre-commit install -``` - -### Running Tests - -Run tests with tox (will test against multiple Python versions): - -```bash -tox -``` - -Run tests for a specific Python version: - -```bash -tox -e py39 # For Python 3.9 -``` - -### Code Quality - -This project uses several tools to maintain code quality: - -- **pre-commit**: Runs various checks before each commit -- **black**: Code formatting -- **isort**: Import sorting -- **flake8**: Style guide enforcement - -Run all code quality checks manually: - -```bash -pre-commit run --all-files -``` - -## Contributing - -🙌 PRs and contributions are welcome! Let's build a better Helm secret & config manager together. - -Please see our [Contributing Guide](CONTRIBUTING.md) for details on how to contribute to this project. - -## Acknowledgments - -We would like to acknowledge the following AI tools that have helped in the development of this project: - -- **[Windsurf IDE with Cascade](https://codeium.com/windsurf)**: For providing intelligent code assistance and pair programming capabilities. Also for helping with improving and documenting the architecture. -- **[Software Architect GPT](https://chatgpt.com/g/g-J0FYgDhN5-software-architect-gpt)**: For initial architectural guidance and design decisions. - -While these AI tools have been valuable in our development process, all code and design decisions have been carefully reviewed and validated by our development team to ensure quality and security. - -## 📌 License - -🔓 Open-source under the [MIT License](LICENSE). - -### 🌟 Star this repo if you find it useful! 🌟 - -[![Star](https://img.shields.io/github/stars/zipstack/helm-values-manager?style=social)](https://github.com/zipstack/helm-values-manager) diff --git a/docs/Commands/README.md b/docs/Commands/README.md new file mode 100644 index 0000000..e69de29