Skip to main content

Publish Allure static reports to private S3 behind CloudFront with history preservation

Project description

pytest-allure-host

CI CodeQL PyPI - Version License: MIT Docs CDK Stack

Publish Allure static reports to private S3 behind CloudFront with history preservation and SPA-friendly routing.

Optional infrastructure (AWS CDK stack to provision the private S3 bucket + CloudFront OAC distribution) lives externally: https://github.com/darrenrabbs/allurehosting-cdk

See docs/architecture.md and .github/copilot-instructions.md for architecture and design constraints.

Documentation

Full documentation (quickstart, AWS setup, IAM least-privilege, CLI usage, changelog) is published at:

https://darrenrabbs.github.io/allurehosting/

The README intentionally stays lean—refer to the site for detailed guidance.

Features

  • Generate Allure static report from allure-results
  • Preserve history by pulling latest/history before generation
  • Upload to S3 under <project>/<branch>/<run_id>/ and update <project>/<branch>/latest/
  • Two-phase latest update: upload to latest_tmp/, swap into latest/, write LATEST_READY marker
  • Optional retention: keep only N newest runs (--max-keep-runs)
  • Correct caching headers: index.html and widgets/no-cache; assets → immutable
  • Optional TTL tagging on objects (--ttl-days) for S3 lifecycle policies
  • Optional summary JSON output for CI
  • Best-effort manifest at runs/index.json with new run metadata
  • Lightweight pointer file latest.json (branch root)
  • Human-friendly HTML index at runs/index.html for navigating past runs
    • Columns: Run ID, raw epoch, UTC Time (human readable), Size (pretty units), P/F/B (passed/failed/broken counts), links to the immutable run and the moving latest
    • Newest run highlighted with a star (★) and soft background

Quick start

# Install the publisher
pip install pytest-allure-host

# Run your test suite and produce allure-results/
pytest --alluredir=allure-results

# Plan (no uploads) – shows what would be published
publish-allure \
  --bucket my-allure-bucket \
  --project myproj \
  --branch main \
  --dry-run --summary-json plan.json

# Real publish (requires AWS creds: env vars, profile, or OIDC)
publish-allure \
  --bucket my-allure-bucket \
  --project myproj \
  --branch main

Notes:

  • --prefix defaults to reports; omit unless you need a different root.
  • --branch defaults to $GIT_BRANCH or main if unset.
  • Add --cloudfront https://reports.example.com to print CDN URLs.
  • Use --check to preflight (AWS / allure binary / inputs) before a real run.
  • Add --context-url https://jira.example.com/browse/PROJ-123 to link a change ticket in the runs index.
  • Use --dry-run + --summary-json in CI for a planning stage artifact.
  • Provide --ttl-days and/or --max-keep-runs for lifecycle & cost controls.

Requirements

  • Python 3.9+
  • AWS credentials with S3 access to the target bucket
  • Allure commandline available on PATH (e.g., via Allure CLI or allure-pytest)

S3 layout and caching

  • Keys:
    • s3://<bucket>/<prefix>/<project>/<branch>/<run_id>/...
    • s3://<bucket>/<prefix>/<project>/<branch>/latest/...
    • s3://<bucket>/<prefix>/<project>/<branch>/runs/index.json (manifest)
    • s3://<bucket>/<prefix>/<project>/<branch>/runs/index.html (HTML index)
    • s3://<bucket>/<prefix>/<project>/<branch>/latest.json (pointer)
  • Two-phase swap writes a LATEST_READY marker file under latest/ when ready.
  • Cache-Control:
    • index.html: no-cache
    • files under widgets/: no-cache
    • everything else: public, max-age=31536000, immutable

CLI usage

Install locally for development:

pip install -e .[dev]

Run the publisher after tests generate allure-results:

publish-allure \
  --bucket your-bucket \
  --prefix reports \
  --project demo \
  --branch main \
  --cloudfront https://reports.example.com \
  --ttl-days 30 \
  --max-keep-runs 10

Flags (CLI):

  • --bucket (required): S3 bucket name
  • --prefix (default: reports): Root prefix
  • --project (required): Project name
  • --branch (default: $GIT_BRANCH or main)
  • --run-id (default: $ALLURE_RUN_ID or YYYYMMDD-HHMMSS)
  • --cloudfront (optional; default: $ALLURE_CLOUDFRONT)
  • --results (default: allure-results): Input directory
  • --report (default: allure-report): Output directory
  • --ttl-days (optional): Add ttl-days=<N> object tag
  • --max-keep-runs (optional): Keep N newest run prefixes, delete older
  • --summary-json <path>: Write machine-readable summary
  • --check: Preflight validation (AWS access, allure, inputs)
  • --dry-run: Print planned prefixes and sample headers, no upload
  • --s3-endpoint: Custom S3 endpoint (e.g. http://localhost:4566 for LocalStack)

Environment fallbacks:

  • GIT_BRANCH--branch default
  • ALLURE_RUN_ID--run-id default
  • ALLURE_CLOUDFRONT--cloudfront default
  • ALLURE_S3_ENDPOINT--s3-endpoint default (LocalStack / custom S3)

Pytest plugin usage

Run tests and publish during terminal summary:

pytest \
  --allure-bucket your-bucket \
  --allure-prefix reports \
  --allure-project demo \
  --allure-branch main \
  --allure-cloudfront https://reports.example.com \
  --allure-ttl-days 30 \
  --allure-max-keep-runs 10

Flags (pytest):

  • --allure-bucket (required)
  • --allure-prefix (default: reports)
  • --allure-project (required)
  • --allure-branch (default: $GIT_BRANCH or main)
  • --allure-run-id (default: $ALLURE_RUN_ID or YYYYMMDD-HHMMSS)
  • --allure-cloudfront (optional; default: $ALLURE_CLOUDFRONT)
  • --allure-ttl-days (optional)
  • --allure-max-keep-runs (optional)
  • --allure-summary-json <path> (optional)
  • --allure-check / --allure-dry-run (optional)

Preflight and dry-run

  • --check/--allure-check verifies:
    • S3 bucket reachability (HeadBucket/List)
    • allure-results exists and is non-empty
    • Allure CLI exists on PATH
  • --dry-run/--allure-dry-run prints planned prefixes and sample headers; no uploads occur.

Outputs

  • S3 prefixes: run and latest
  • Optional CDN URLs (if --cloudfront provided)
  • runs/index.json manifest updated with new run entry
  • runs/index.html HTML table of recent runs (newest first) with columns: Run ID, Epoch, UTC Time, Size, P/F/B, Run, Latest (newest row highlighted with ★)
  • latest.json pointer to current run (simple machine-readable metadata)
  • Optional --summary-json with sizes, file counts, and destination URLs
  • latest/LATEST_READY marker indicates the swap is complete

Security

See SECURITY.md for how to report vulnerabilities. Never open a public issue containing sensitive details.

Badges / Status

  • CI: multi-version test matrix + lint/security
  • CodeQL: static code analysis

Contributing

See CONTRIBUTING.md and follow the pre-commit hooks (pre-commit install).

Release

Tagged versions (vX.Y.Z) are published to PyPI automatically via GitHub OIDC.

CI examples

GitHub Actions (CLI):

jobs:
  tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: { python-version: "3.11" }
      - run: pip install .[dev]
      - run: pytest -q
      - name: Publish Allure
        env:
          AWS_REGION: us-east-1
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          GIT_BRANCH: ${{ github.ref_name }}
        run: >-
          publish-allure --bucket $BUCKET --prefix reports --project demo
          --branch "$GIT_BRANCH" --cloudfront https://reports.example.com
          --ttl-days 30 --max-keep-runs 10

Pytest-driven (plugin):

- run: pytest -q \
    --allure-bucket $BUCKET \
    --allure-prefix reports \
    --allure-project demo \
    --allure-branch "$GIT_BRANCH" \
    --allure-cloudfront https://reports.example.com \
    --allure-ttl-days 30 \
    --allure-max-keep-runs 10

Minimal publish-only workflow

Create .github/workflows/allure-publish.yml for a lightweight pipeline that runs tests, generates the report, and publishes it (using secrets for the bucket and AWS credentials):

name: allure-publish
on: [push, pull_request]
jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.11"
      - name: Install deps (minimal)
        run: pip install pytest pytest-allure-host allure-pytest
      - name: Run tests
        run: pytest --alluredir=allure-results -q
      - name: Publish Allure report (dry-run on PRs)
        env:
          AWS_REGION: us-east-1
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          ALLURE_BUCKET: ${{ secrets.ALLURE_BUCKET }}
        run: |
          EXTRA=""
          if [ "${{ github.event_name }}" = "pull_request" ]; then EXTRA="--dry-run"; fi
          publish-allure \
            --bucket "$ALLURE_BUCKET" \
            --project myproj \
            --branch "${{ github.ref_name }}" \
            --summary-json summary.json $EXTRA
      - name: Upload publish summary (always)
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: allure-summary
          path: summary.json

Notes:

  • Add --cloudfront https://reports.example.com if you have a CDN domain.
  • Add --context-url ${{ github.server_url }}/${{ github.repository }}/pull/${{ github.event.pull_request.number }} inside PRs to link the run to its PR.
  • Use --max-keep-runs / --ttl-days to manage storage costs.
  • For LocalStack-based tests, set --s3-endpoint and export ALLURE_S3_ENDPOINT in env:.

Troubleshooting

  • Missing Allure binary: ensure the Allure CLI is installed and on PATH.
  • Access denied: verify AWS credentials and bucket IAM for Put/Get/List/Delete.
  • SPA routing 403/404: configure CloudFront error mapping to /index.html.

Development

  • Install with Poetry: poetry install
  • Run tests: poetry run pytest -q
  • Lint (security quick): poetry run bandit -r pytest_allure_host
  • Unified lint helper (mirrors CI):
    scripts/lint.sh           # check mode (ruff lint+format check, bandit, pip-audit)
    scripts/lint.sh --fix     # apply ruff fixes + format
    scripts/lint.sh pre-commit  # also run pre-commit hooks on all files
    

Quick local trial (macOS)

This section walks you through a minimal end-to-end run locally.

  1. Prereqs
  • AWS credentials configured (via AWS_PROFILE or access keys); set AWS_REGION.
  • Allure CLI installed on PATH:
    brew install allure
    
  • Python deps installed:
    poetry install
    # or
    pip install -e .[dev]
    
  1. Generate Allure results
  • Create a tiny test (optional example):
    mkdir -p tests
    cat > tests/test_sample.py <<'PY'
    def test_ok():
        assert True
    PY
    
  • Run pytest to emit results:
    poetry run pytest --alluredir=allure-results
    
  1. Preflight and dry-run
poetry run publish-allure \
  --bucket <bucket> \
  --prefix reports \
  --project demo \
  --branch $(git rev-parse --abbrev-ref HEAD) \
  --cloudfront https://<cloudfront_domain> \
  --check \
  --dry-run
  1. Publish
poetry run publish-allure \
  --bucket <bucket> \
  --prefix reports \
  --project demo \
  --branch $(git rev-parse --abbrev-ref HEAD) \
  --cloudfront https://<cloudfront_domain> \
  --ttl-days 30 \
  --max-keep-runs 5
  1. Verify
  • S3: reports/demo/<branch>/<run_id>/... and reports/demo/<branch>/latest/ with LATEST_READY.
  • CDN: open printed run_url / latest_url.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytest_allure_host-2.0.0.tar.gz (47.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pytest_allure_host-2.0.0-py3-none-any.whl (47.7 kB view details)

Uploaded Python 3

File details

Details for the file pytest_allure_host-2.0.0.tar.gz.

File metadata

  • Download URL: pytest_allure_host-2.0.0.tar.gz
  • Upload date:
  • Size: 47.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pytest_allure_host-2.0.0.tar.gz
Algorithm Hash digest
SHA256 ec87d0595af6b234175d32e343b598c6ffac1fe5041aaf64b07cb1e3230947f5
MD5 30bd09672a1ae21e18ce336617192bc3
BLAKE2b-256 81de70e4f5d220d5b3b426dbd4e9fce78400024cb116ee99712807233af85f62

See more details on using hashes here.

Provenance

The following attestation bundles were made for pytest_allure_host-2.0.0.tar.gz:

Publisher: release.yml on darrenrabbs/allurehosting

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pytest_allure_host-2.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for pytest_allure_host-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 40c40fdcc5e73e2369c08de78e3c84173f86eefb85c31caad378c5d40e8f6fed
MD5 b9a7369279c383d13c42c53396a74f5c
BLAKE2b-256 b62a827dc35df9850c17f27a9fc2d7611d60cd6d1c76e453bd96419b7eb873ad

See more details on using hashes here.

Provenance

The following attestation bundles were made for pytest_allure_host-2.0.0-py3-none-any.whl:

Publisher: release.yml on darrenrabbs/allurehosting

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page