diff --git a/.github/workflows/_build-docs.yml b/.github/workflows/_build-docs.yml new file mode 100644 index 00000000..3c6c29ff --- /dev/null +++ b/.github/workflows/_build-docs.yml @@ -0,0 +1,17 @@ +name: build-docs +on: + workflow_call: +jobs: + build: + name: Build docs + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: 3.12 + - name: Install build dependencies + run: pip install --no-cache-dir -U pip .['docs'] + - name: Build docs + run: ./scripts/cd.py --build-docs \ No newline at end of file diff --git a/.github/workflows/_deploy-docs.yml b/.github/workflows/_deploy-docs.yml new file mode 100644 index 00000000..3d7ed0b4 --- /dev/null +++ b/.github/workflows/_deploy-docs.yml @@ -0,0 +1,25 @@ +name: deploy-docs +on: + workflow_call: +jobs: + upload: + name: Deploy docs to github pages + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Compare tag and package version + run: | + TAG=${GITHUB_REF#refs/*/} + VERSION=$(grep -Po '(?<=version = ")[^"]*' pyproject.toml) + if [ "$TAG" != "$VERSION" ]; then + echo "Tag value and package version are different: ${TAG} != ${VERSION}" + exit 1 + fi + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: 3.12 + - name: Install build dependencies + run: pip install --no-cache-dir -U pip .['docs'] + - name: Deploy to github pages + run: ./scripts/cd.py --deploy-docs diff --git a/.github/workflows/main-cicd.yml b/.github/workflows/main-cicd.yml index 9bc6dc22..a7bc0aca 100644 --- a/.github/workflows/main-cicd.yml +++ b/.github/workflows/main-cicd.yml @@ -16,9 +16,14 @@ jobs: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} build-package: uses: ./.github/workflows/_build-package.yml + build-docs: + uses: ./.github/workflows/_build-docs.yml upload-package: uses: ./.github/workflows/_upload-package.yml if: startsWith(github.ref, 'refs/tags/') - needs: [static-checks, integration-tests, build-package] + needs: [static-checks, integration-tests, build-package, build-docs] secrets: PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} + deploy-docs: + uses: ./.github/workflows/_deploy-docs.yml + needs: [upload-package] diff --git a/.gitignore b/.gitignore index 61961588..ac851a23 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,15 @@ +# generic __pycache__/ thehive4py.egg-info/ build/ dist/ -venv/ -tmp/ -# local garbage yet -tests/resources/ -examples/ +# pytest +.coverage +coverage.xml + +# mkdocs +site/ + +# misc +tmp/ diff --git a/LICENSE b/LICENSE index 78103b04..621b7cf1 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 StrangeBee +Copyright (c) 2024 StrangeBee Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index d5503182..19f19803 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,11 @@ thehive4py - the de facto Python API client of TheHive

+ + release + - cicd + build codecov diff --git a/docs/img/strangebee.png b/docs/img/strangebee.png new file mode 100644 index 00000000..9b11d2e9 Binary files /dev/null and b/docs/img/strangebee.png differ diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..65a0ce48 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,33 @@ +--- +title: Coming Soon! +hide: + - toc + - navigation +--- +# +

+

+ TheHive4py + + TheHive Logo + +

+

+ :material-bee:{ .strangebee .bluebee .upleftbee } + :material-bee:{ .strangebee .yellowbee .upbee } + :material-bee:{ .strangebee .bluebee .uprightbee } +

+ Coming Soon! +

+ :material-bee:{ .strangebee .yellowbee .downleftbee } + :material-bee:{ .strangebee .bluebee .downbee } + :material-bee:{ .strangebee .yellowbee .downrightbee } +

+ + + +

Our bees are out buzzing to gather all the docs you need!

+

Check out our Quickstart in the meantime!

+
+ + diff --git a/docs/styles/extra.css b/docs/styles/extra.css new file mode 100644 index 00000000..7a77407c --- /dev/null +++ b/docs/styles/extra.css @@ -0,0 +1,64 @@ +:root { + --md-primary-fg-color: #0049d4; + --md-accent-fg-color: #ffc72c; +} + +@keyframes pulse { + 0%, 100% { + transform: scale(1); + } + 50% { + transform: scale(1.25); + } + } + + +.coming-soon { + color: var(--md-primary-fg-color); + font-size: 1.5rem; + font-weight: bold; + transition: 0.75s; +} + +.coming-soon:hover{ + color: var(--md-accent-fg-color); + transition: 0.75s; +} + +.upleftbee { + rotate: -90deg; +} + +.upbee { + rotate: -45deg; +} + +.uprightbee{ + rotate: 0deg; +} + +.downleftbee { + rotate: 180deg; +} + +.downbee { + rotate: 135deg; +} + +.downrightbee{ + rotate: 90deg; +} + +.yellowbee { + color: var(--md-accent-fg-color) +} + +.bluebee { + color: var(--md-primary-fg-color) +} + +.strangebee { + animation: pulse 2s infinite; + font-size: 1.5rem; + vertical-align: top !important; +} diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 00000000..9c0d51e4 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,49 @@ +site_name: TheHive4py +theme: + name: material + favicon: img/strangebee.png + logo: img/strangebee.png + features: + - navigation.footer + palette: + - media: "(prefers-color-scheme)" + toggle: + icon: material/lightbulb-auto + name: Switch to light mode + - media: '(prefers-color-scheme: light)' + scheme: default + primary: custom + accent: custom + toggle: + icon: material/lightbulb + name: Switch to dark mode + - media: '(prefers-color-scheme: dark)' + scheme: slate + primary: custom + accent: custom + toggle: + icon: material/lightbulb-outline + name: Switch to system preference +extra_css: + - styles/extra.css +repo_name: TheHive-Project/TheHive4py +repo_url: https://github.com/TheHive-Project/TheHive4py +markdown_extensions: + - attr_list + - md_in_html + - pymdownx.emoji: + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg +extra: + social: + - icon: simple/discord + link: https://discord.com/invite/XhxG3vzM44 + name: Discord + - icon: simple/github + link: https://github.com/TheHive-Project/TheHive4py + name: GitHub + - icon: simple/python + link: https://pypi.org/project/thehive4py/ + name: PyPI + + diff --git a/pyproject.toml b/pyproject.toml index 99f373d7..7ddc9034 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,6 +28,7 @@ authors = [{ name = "Szabolcs Antal", email = "antalszabolcs01@gmail.com" }] [project.optional-dependencies] audit = ["bandit", "pip-audit"] build = ["build", "twine"] +docs = ["mkdocs", "mkdocs-material"] lint = ["black", "flake8-pyproject", "mypy", "pre-commit"] test = ["pytest", "pytest-cov"] dev = ["thehive4py[audit, lint, test, build]"] diff --git a/scripts/cd.py b/scripts/cd.py index 039313a7..bf366e00 100755 --- a/scripts/cd.py +++ b/scripts/cd.py @@ -1,7 +1,7 @@ #!/usr/bin/env python import argparse import subprocess -from typing import List +from typing import Dict def _run_subprocess( @@ -23,13 +23,6 @@ def _run_subprocess( exit(err.returncode) -def run_all(quiet=False): - print("Run all deployment tasks...") - run_build(quiet=quiet) - run_upload(quiet=quiet) - print("All tasks succeeded!") - - def run_build(quiet: bool): print("Building thehive4py with the build module...") _run_subprocess( @@ -52,14 +45,34 @@ def run_upload(quiet: bool): print("Successfully published thehive4py!") -def build_run_options() -> List[dict]: - return [ - {"name": "build", "help": "run build step", "func": run_build}, - {"name": "upload", "help": "run upload step", "func": run_upload}, - ] +def run_build_docs(quiet: bool): + print("Building thehive4py docs...") + _run_subprocess( + command="mkdocs build --clean --strict", + quiet=quiet, + ) + print("Successfully built thehive4py docs!") -def parse_arguments(run_options: List[dict]): +def run_deploy_docs(quiet: bool): + print("Deploying thehive4py docs to gh-pages...") + _run_subprocess( + command="mkdocs gh-deploy --force", + quiet=quiet, + ) + print("Successfully deployed thehive4py docs to gh-pages!") + + +def build_run_options() -> Dict[str, dict]: + return { + "build": {"help": "build the package locally", "func": run_build}, + "upload": {"help": "upload the package to pypi", "func": run_upload}, + "build-docs": {"help": "build the docs locally", "func": run_build_docs}, + "deploy-docs": {"help": "deploy the docs to gh-pages", "func": run_deploy_docs}, + } + + +def parse_arguments(run_options: Dict[str, dict]): parser = argparse.ArgumentParser( prog="thehive4py-cd", description="run all cd steps or use options to run cd steps selectively", @@ -72,14 +85,21 @@ def parse_arguments(run_options: List[dict]): help="silence verbose output", ) - for run_option in run_options: + for run_option_name, run_option_attributes in run_options.items(): parser.add_argument( - f"--{run_option['name']}", - help=run_option["help"], + f"--{run_option_name.replace('_', '-')}", + help=run_option_attributes["help"], action="store_true", ) - return parser.parse_args() + args = parser.parse_args() + + if not any( + getattr(args, run_option.replace("-", "_")) for run_option in run_options + ): + parser.error(f"provide at least one option from: {list(run_options)}") + + return args def main(): @@ -88,17 +108,17 @@ def main(): quiet = args.quiet - selective_runs = [ - run_option["func"] - for run_option in run_options - if getattr(args, run_option["name"]) + selected_run_funcs = [ + run_option_attributes["func"] + for run_option_name, run_option_attributes in run_options.items() + if getattr(args, run_option_name.replace("-", "_")) ] - if selective_runs: - for run in selective_runs: - run(quiet=quiet) - else: - run_all(quiet=quiet) + for run_func in selected_run_funcs: + run_func(quiet=quiet) + print() + + print("Done!") if __name__ == "__main__":