Metadata-Version: 2.4
Name: mkdocs_sharepoint_plugin
Version: 1.2.5
Summary: MkDocs plugin to publish documentation to SharePoint
Author-email: Surj Bains <surjit.bains@gmail.com>
Requires-Python: >=3.7
Description-Content-Type: text/markdown
Requires-Dist: requests
Requires-Dist: pyyaml<7.0,>=6.0
Requires-Dist: mkdocs
Requires-Dist: Office365-REST-Python-Client>=2.5.0
Requires-Dist: tenacity>=8.2
Provides-Extra: dev
Requires-Dist: mkdocs; extra == "dev"
Requires-Dist: pytest==8.0.0; extra == "dev"
Requires-Dist: pytest-mock==3.12.0; extra == "dev"
Requires-Dist: coverage==7.5; extra == "dev"
Requires-Dist: pre-commit; extra == "dev"
Requires-Dist: black; extra == "dev"

<p align="center">
  <img src="docs/hero.svg" alt="MkDocs SharePoint Plugin — publish MkDocs documentation to SharePoint Online" width="100%" />
</p>

# MkDocs SharePoint Plugin

[![Python CI](https://img.shields.io/github/actions/workflow/status/polarpoint-io/python-mkdocs-to-sharepoint/python-app.yaml?branch=main&label=python%20ci)](https://github.com/polarpoint-io/python-mkdocs-to-sharepoint/actions/workflows/python-app.yaml)
[![codecov](https://img.shields.io/codecov/c/github/polarpoint-io/python-mkdocs-to-sharepoint?branch=main&logo=codecov)](https://codecov.io/gh/polarpoint-io/python-mkdocs-to-sharepoint)
[![PyPI version](https://img.shields.io/pypi/v/mkdocs_sharepoint_plugin.svg)](https://pypi.org/project/mkdocs_sharepoint_plugin/)
[![GHCR](https://img.shields.io/badge/ghcr.io-python--mkdocs--to--sharepoint-blue?logo=github)](https://github.com/polarpoint-io/python-mkdocs-to-sharepoint/pkgs/container/python-mkdocs-to-sharepoint)

A MkDocs plugin that automatically publishes your built documentation site to SharePoint Online, with Microsoft Graph API support and static HTML preservation.

## Features

- **Automatic publishing** - Upload the MkDocs `site_dir` output to SharePoint during `mkdocs build`
- **Microsoft Graph API** - Default upload path using Graph API (`upload_api: graph`)
- **SharePoint REST API** - Optional legacy upload path (`upload_api: rest`)
- **Folder structure preservation** - Maintains subdirectories when uploading to a document library
- **Static HTML support** - Preserves MkDocs theme features such as admonitions, navigation, TOC, and generated assets
- **App-based authentication** - Uses Microsoft Entra app credentials (client ID/secret)
- **Flexible configuration** - Config values with environment variable fallbacks
- **Dry-run mode** - Test your configuration without publishing
- **Debug mode** - Detailed logging for troubleshooting
- **Retry support** - Exponential backoff for transient SharePoint API failures
- **Docker image** - Versioned container published to GitHub Container Registry

## Installation

### Install from Source

```shell
pip install .
```

### Development Installation

For development with optional dependencies:

```shell
pip install -e ".[dev]"
```

### Build from Source

Using modern Python build tools:

```shell
python -m build
pip install dist/mkdocs_sharepoint_plugin-*.whl
```

### Additional MkDocs Plugins (Optional)

Install additional MkDocs plugins as needed for your documentation:

```shell
# Popular MkDocs plugins for enhanced documentation
pip install mkdocs-material mkdocs-awesome-nav
pip install mkdocs-build-plantuml-plugin mkdocs-git-revision-date-localized-plugin
```

## Python Requirements

- **Python:** >=3.7
- **Build System:** setuptools>=61, wheel, build

## Dependencies

### Core Dependencies (from pyproject.toml)
- **mkdocs** - The static site generator this plugin extends
- **Office365-REST-Python-Client** - SharePoint REST API client
- **tenacity** - Retry/backoff for API calls
- **requests** - HTTP library for API calls
- **pyyaml** - YAML parsing library

### Testing Dependencies
- **pytest==8.0.0** - Testing framework
- **pytest-mock==3.12.0** - Mocking utilities for tests
- **coverage==7.5** - Code coverage analysis
- **pre-commit** - Git hook management

### Development Dependencies (Optional)
Install with: `pip install -e ".[dev]"`
- **black** - Code formatting
- **mkdocs** - For local testing
- **pytest** - Testing framework
- **coverage** - Coverage reporting

### Recommended MkDocs Plugins
These plugins work well with the SharePoint plugin but are installed separately:
- **mkdocs-awesome-nav** - Advanced navigation management with `.nav.yml` files
- **mkdocs-material** - Modern Material Design theme
- **mkdocs-build-plantuml-plugin** - PlantUML diagram support
- **mkdocs-git-revision-date-localized-plugin** - Git-based page timestamps

## Configuration

The plugin is automatically registered as a MkDocs plugin via the entry point:

```
sharepoint = "mkdocs_sharepoint_plugin.plugin:SharePointPlugin"
```

Add the plugin to your `mkdocs.yml` configuration:

```yaml
plugins:
  - awesome-nav:
      filename: ".nav.yml"
  - sharepoint:
      site_url: https://contoso.sharepoint.com/sites/Team
      tenant_id: your-tenant-id
      documents_folder: /sites/Team/Shared Documents/Docs
      upload_api: graph
      enabled_if_env: MKDOCS_TO_SHAREPOINT
      dryrun: false
      debug: false
```

### Configuration Options

| Option | Description | Default | Required |
|--------|-------------|---------|----------|
| `site_url` | SharePoint site URL | `$SHAREPOINT_SITE_URL` | ✅ |
| `client_id` | Entra app client ID | `$SHAREPOINT_CLIENT_ID` | ✅ |
| `client_secret` | Entra app client secret | `$SHAREPOINT_CLIENT_SECRET` | ✅ |
| `tenant_id` | Entra tenant ID | `$SHAREPOINT_TENANT_ID` / `$AZURE_TENANT_ID` | ✅ for Graph |
| `documents_folder` | Server-relative document library folder | | ✅ |
| `publish_site_url` | Public URL prefix for uploaded HTML (auto-derived from `site_url` + `documents_folder` if omitted) | auto | |
| `inject_base_href` | Inject `<base href>` and SharePoint hosting compatibility shim into built HTML | `true` | |
| `html_file_extension` | Publish HTML pages as `.aspx` so SharePoint opens them in the browser (`html` or `aspx`) | `html` | |
| `pages_folder` | Server-relative Site Pages folder (for wiki helpers) | `null` | |
| `upload_api` | Upload API: `graph` or `rest` | `graph` | |
| `enabled_if_env` | Environment variable to enable plugin | | |
| `dryrun` | Test mode without publishing | `false` | |
| `debug` | Enable debug logging | `false` | |

### SharePoint static hosting

SharePoint document libraries are not static site hosts. When you preview an HTML file in the library UI, SharePoint loads it in a sandboxed `about:srcdoc` iframe. MkDocs Material resolves URLs from `location`, which breaks in that context and can surface console errors such as `Failed to construct 'URL'` and `__md_get is not defined`.

When `inject_base_href` is enabled (default), the plugin:

1. Sets MkDocs `site_url` to the derived `publish_site_url` so assets use absolute URLs.
2. Injects a `<base href>` and a small URL-constructor shim into every built HTML file before upload.

For the best reading experience, open `index.aspx` (when using `html_file_extension: aspx`) or `index.html` directly in a new browser tab instead of using the SharePoint preview pane.

SharePoint Online uses strict browser file handling: `.html` files in document libraries are downloaded instead of rendered. Set `html_file_extension: aspx` and `use_directory_urls: false` in your MkDocs config so pages publish as `.aspx` files with direct links between pages.

## Usage

### Basic Usage

1. Configure the plugin in your `mkdocs.yml`
2. Set up environment variables for SharePoint authentication:
   ```bash
   export SHAREPOINT_SITE_URL=https://contoso.sharepoint.com/sites/Team
   export SHAREPOINT_CLIENT_ID=your-client-id
   export SHAREPOINT_CLIENT_SECRET=your-client-secret
   export SHAREPOINT_TENANT_ID=your-tenant-id
   export MKDOCS_TO_SHAREPOINT=1
   ```
3. Build and publish your documentation:
   ```bash
   mkdocs build
   ```

When `enabled_if_env` is set, the plugin only publishes when the environment variable equals `1`.

### Using with mkdocs-awesome-nav

For complex navigation structures, use `mkdocs-awesome-nav` with a `.nav.yml` file:

```yaml
# docs/.nav.yml
nav:
  - Index: index.md

  - Support:
      - support/*.md
      - support/**/*.md

  - Technical-Practices:
      - Architecture Design Records:
          - technical-practices/architecture_design_records/*.md
          - technical-practices/architecture_design_records/**/*.md
```

### Environment Setup

Set up the required environment variables for SharePoint authentication and plugin configuration:

```bash
# Required for SharePoint authentication
export SHAREPOINT_SITE_URL="https://contoso.sharepoint.com/sites/Team"
export SHAREPOINT_CLIENT_ID="your-client-id"
export SHAREPOINT_CLIENT_SECRET="your-client-secret"
export SHAREPOINT_TENANT_ID="your-tenant-id"

# Plugin enablement
export MKDOCS_TO_SHAREPOINT=1
```

**Required Environment Variables:**
- `SHAREPOINT_SITE_URL` - SharePoint site URL
- `SHAREPOINT_CLIENT_ID` - Entra app client ID
- `SHAREPOINT_CLIENT_SECRET` - Entra app client secret
- `SHAREPOINT_TENANT_ID` - Entra tenant ID (required for Graph uploads)
- `MKDOCS_TO_SHAREPOINT` - Set to `1` to enable the plugin

### Dry Run Mode

Test your configuration without publishing to SharePoint:

```yaml
plugins:
  - sharepoint:
      # ... other config ...
      dryrun: true
      debug: true
```

## SharePoint API Helpers

The repo also includes helper functions and an optional CLI for direct SharePoint publishing outside MkDocs:

- Module: `src/mkdocs_sharepoint_plugin/sharepoint_publish.py`
- Graph module: `src/mkdocs_sharepoint_plugin/graph_publish.py`
- CLI: `tools/sharepoint_publish.py`

Example CLI usage:

```shell
python tools/sharepoint_publish.py upload-docs \
    --local-dir site \
    --server-folder "/sites/your-site/Shared Documents/Docs" \
    --upload-api graph

python tools/sharepoint_publish.py create-wiki \
    --title "How do I reset my password?" \
    --html-file page.html \
    --pages-folder "/sites/your-site/SitePages"
```

## Testing

### Run All Tests

Tests are configured via pyproject.toml with optimized settings:

```shell
# Run tests with project settings (maxfail=1, no warnings, quiet)
python -m pytest tests/

# Or run with verbose output
python -m pytest tests/ -v
```

**Test Configuration (from pyproject.toml):**
- Test directory: `tests/`
- Max failures: 1 (stops after first failure)
- Warnings disabled for cleaner output
- Quiet mode by default

### Coverage Report

The project is configured for comprehensive coverage reporting with a minimum threshold:

```shell
coverage run --source=src -m pytest -vv tests/
coverage report
coverage html
```

**Coverage Settings (from pyproject.toml):**
- Branch coverage enabled
- Source directory: `src`
- Minimum coverage: 30%
- Shows missing lines in reports

## Code Quality

### Code Formatting

We use [Black](https://black.readthedocs.io/) for consistent code formatting:

```shell
black src tests
```

## Development

### Local Development Setup

1. Clone the repository
2. Install the package with development dependencies: `pip install -e ".[dev]"`
3. Install additional MkDocs plugins if needed: `pip install mkdocs-material mkdocs-awesome-nav`
4. Set up environment variables:
   ```bash
   export SHAREPOINT_SITE_URL=https://contoso.sharepoint.com/sites/Team
   export SHAREPOINT_CLIENT_ID=your-client-id
   export SHAREPOINT_CLIENT_SECRET=your-client-secret
   export SHAREPOINT_TENANT_ID=your-tenant-id
   export MKDOCS_TO_SHAREPOINT=1
   ```
5. Run tests: `python -m pytest tests/`

### Build System

The project uses modern Python packaging with `pyproject.toml`:

```shell
python -m build
pip install dist/mkdocs_sharepoint_plugin-*.whl
```

**Build Configuration:**
- Build system: setuptools>=61, wheel, build
- Package discovery: automatic from `src/` directory
- Entry point: `sharepoint = "mkdocs_sharepoint_plugin.plugin:SharePointPlugin"`

### Versioning

The project uses semantic versioning with automated releases:
- Version managed in `pyproject.toml`
- Semantic release configured for automated version bumps
- Current version: 1.1.1

### Testing Your Changes

1. Run the full test suite: `python -m pytest tests/ -v`
2. Test with a real MkDocs build: `mkdocs build -f mkdocs.dryrun.yaml`
3. Use dry-run mode to test SharePoint integration without publishing

### Contributing

1. Ensure all tests pass
2. Format code with Black: `black src tests`
3. Add tests for new functionality
4. Update documentation as needed

## Docker Image

Releases publish a versioned container image to GitHub Container Registry via [`@codedependant/semantic-release-docker`](https://www.npmjs.com/package/@codedependant/semantic-release-docker):

```
ghcr.io/polarpoint-io/python-mkdocs-to-sharepoint:<version>
```

Example usage:

```shell
docker run --rm -v "$PWD:/docs" -w /docs \
  ghcr.io/polarpoint-io/python-mkdocs-to-sharepoint:latest build
```

Tags follow semantic versioning (`latest`, `1.2.3`, `1-latest`, `1.2`).

## Architecture

The plugin publishes MkDocs output using one of two upload APIs:

- **Graph API (`upload_api: graph`)** - Recommended default. Uses Microsoft Graph to upload files to a document library and works with `Sites.Selected` app permissions.
- **SharePoint REST API (`upload_api: rest`)** - Legacy path using `Office365-REST-Python-Client`. Requires SharePoint REST access to the target site.

Publishing flow:

1. MkDocs builds the static site to `site_dir`
2. `on_post_build` walks all files under `site_dir`
3. Files are uploaded to `documents_folder`, preserving subdirectory structure
4. SharePoint serves the static HTML, CSS, JS, fonts, and generated assets

## Authentication Notes

SharePoint Online automation typically uses app-only authentication in Microsoft Entra ID. The app needs appropriate SharePoint permissions (for example `Sites.ReadWrite.All` or `Sites.Selected` with site grants) and admin consent for the tenant.

Store secrets in environment variables or a secrets manager. Do not commit credentials to source control.

## Related Projects

- [python-mkdocs-to-confluence](https://github.com/polarpoint-io/python-mkdocs-to-confluence) - Sister plugin for publishing MkDocs documentation to Confluence
