Skip to content

Contributing

Thank you for your interest in contributing to azure-functions-logging. This guide covers the contribution workflow, code standards, and release process.

Getting Started

  1. Fork the repository on GitHub.
  2. Clone your fork:
git clone https://github.com/<your-username>/azure-functions-logging.git
cd azure-functions-logging
  1. Install development dependencies:
pip install -e ".[dev]"
  1. Verify your setup:
make check-all

See the Development guide for detailed environment setup.

Contribution Workflow

1. Create a Branch

Create a feature branch from main:

git checkout -b feat/my-feature

2. Make Changes

  • Write your code in src/azure_functions_logging/
  • Add tests in tests/
  • Update documentation in docs/ if behavior changes

3. Run Checks Locally

Before pushing, run the full local gate:

make check-all

This runs:

Check Command
Code formatting make format (ruff)
Linting make style (ruff)
Type checking make typecheck (mypy)
Security scan make security (bandit)
Tests make test (pytest)

4. Commit

Use the Conventional Commits format:

git commit -m "feat: add JsonFormatter for structured logging"

5. Push and Open a PR

git push origin feat/my-feature

Open a pull request against the main branch with a clear description of what changed and why.

Commit Message Format

Type When to Use
feat New feature or capability
fix Bug fix
docs Documentation changes only
style Formatting, whitespace, missing semicolons (no code change)
refactor Code restructuring without changing behavior
test Adding or updating tests
chore Build process, CI, dependency updates

Examples

feat: add JsonFormatter for structured logging
fix: handle missing context object in inject_context
docs: update troubleshooting guide with host.json section
test: add coverage for cold start edge cases
refactor: extract environment detection into separate function
chore: bump mypy to v1.12

Code Standards

Type Safety

  • All public functions and methods must have complete type annotations
  • mypy --strict must pass without errors
  • Do not use Any except where necessary for compatibility (e.g., inject_context(context: Any))
  • Do not use # type: ignore without an inline comment explaining why

Code Style

  • Code is formatted with ruff and linted with ruff
  • Run make format to auto-format before committing
  • Maximum line length: 100 characters (ruff configured)

Error Handling

  • No empty catch blocks
  • Logging-related errors should be caught and handled silently (a logging failure should never crash the application)
  • Include actionable context in error messages

Testing

  • All new features must include tests
  • All bug fixes must include a regression test
  • Tests must pass across the full Python version matrix (3.10-3.14)
  • Coverage should not decrease

Module Conventions

  • Private modules are prefixed with underscore (_setup.py, _logger.py)
  • Public API is exported from __init__.py
  • Each module has a single, clear responsibility
  • No circular imports

Development Commands

Command Description
make format Format code with ruff
make style Lint with ruff
make typecheck Type check with mypy (strict mode)
make lint Run both style and typecheck
make test Run tests with pytest
make cov Run tests and generate coverage report
make security Run bandit security scan
make check-all Run full local gate (all of the above)

Pre-commit Hooks

Install pre-commit hooks to run checks automatically before each commit:

pre-commit install

The hooks run formatting and linting checks. This catches issues before they reach CI.

Pull Request Guidelines

  • Keep PRs focused on a single change
  • Include tests for new functionality
  • Update documentation if public behavior changes
  • Reference related issues in the PR description (e.g., "Fixes #42")
  • Ensure CI passes before requesting review
  • Respond to review feedback promptly

Version Management

Version is stored in src/azure_functions_logging/__init__.py:

__version__ = "0.2.1"

Before creating a release:

  1. Update __version__ in __init__.py
  2. Document all changes in docs/changelog.md
  3. Verify make check-all passes
  4. Commit, tag, and push

Release Process

Releases are triggered by pushing a version tag to GitHub:

# Update version
# Update changelog
git add -A && git commit -m "chore: release v0.3.0"
git tag v0.3.0
git push origin main --tags

The release workflow:

  1. Runs CI (lint, typecheck, security, tests) across the Python version matrix
  2. Builds the package
  3. Publishes to PyPI
  4. Creates a GitHub Release

Architecture Overview

Before making changes, familiarize yourself with the module structure in the Architecture guide. Key points:

  • The library uses Python's standard logging module exclusively
  • Context propagation uses contextvars for thread/async safety
  • FunctionLogger wraps (does not subclass) logging.Logger
  • Environment detection determines setup behavior (Azure vs. local)
  • All public functions are exported from __init__.py

Questions?

Open an issue on GitHub.