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

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

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

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

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

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-0.1.1.tar.gz (19.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-0.1.1-py3-none-any.whl (19.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: pytest_allure_host-0.1.1.tar.gz
  • Upload date:
  • Size: 19.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-0.1.1.tar.gz
Algorithm Hash digest
SHA256 fb9205c3c7ff53b266e79d7af92fdd4a7fad8a40bf0434fb25f973bb40b01058
MD5 ac35919cc89373a38f063f432e313103
BLAKE2b-256 e95ac2f2c976604a024fd23c29b071e2e58c8bfc8da6f9537a3bf415754a8064

See more details on using hashes here.

Provenance

The following attestation bundles were made for pytest_allure_host-0.1.1.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-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for pytest_allure_host-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 20e93e3b7121eb0d75baaa2769966f07f4b5820631c76ddce280e38f47ecd258
MD5 df62252a4ec3413343c833640a8700d1
BLAKE2b-256 b021fc8a672adc4abf3bc536135df3aea5170c415b3a43e386f7280a59e5b4aa

See more details on using hashes here.

Provenance

The following attestation bundles were made for pytest_allure_host-0.1.1-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