CI Integration¶
This page covers practical patterns to publish private Allure reports from CI, assuming a one‑time infra provision has been done (e.g., allurehost-infra-setup --bucket <bucket> --region <region> --yes). Internal release mechanics (tagging, maintainer checklist) live in CONTRIBUTING to keep this page consumer‑focused.
Allure Report Publishing in CI¶
Two typical integration patterns:
1. Direct Pytest Invocation Pipeline¶
sequenceDiagram
participant Dev
participant CI as CI Job
participant Pytest as pytest + plugin
participant S3 as S3 private
participant CF as CloudFront
Dev->>CI: Push code / open PR
CI->>Pytest: Run tests with plugin flags
Pytest->>Pytest: Generate allure-results
Pytest->>S3: Pull latest/history best-effort
Pytest->>Pytest: Generate static Allure report
Pytest->>S3: Upload run_id prefix
Pytest->>S3: Two-phase promote to latest
Pytest->>S3: Update manifest runs/index.json
S3-->>CF: OAC fetch private
Pytest->>CI: Print final run & latest URLs
2. Split Build/Test and Publish Steps¶
Useful when tests and publishing happen in different jobs (e.g. reusing artifacts).
flowchart TB
subgraph T[Test job]
A[Run tests]
end
subgraph P[Publish job]
B[Start publish]
end
A -->|Upload allure-results artifact| B
B --> C[Pull previous latest/history]
C --> D[Generate report]
D --> E[Upload run prefix]
E --> F[Two-phase latest update]
F --> G[Update manifest & HTML index]
G --> H[Output URLs / summary]
classDef phase fill:#e8f4ff,stroke:#1890ff,color:#222
class A,B,C,D,E,F,G,H phase
Key Guarantees¶
- Private delivery via CloudFront + OAC (no S3 website hosting)
- Two‑phase
latest/update and history pull preserve trends and prevent race conditions
Caching Strategy (Implemented / Enforced by Uploader)¶
index.html:Cache-Control: no-cache- Assets (JS/CSS/immutable):
public, max-age=31536000, immutable - Optional:
widgets/set tono-cacheto keep summary live.
Uploader sets headers automatically; no CloudFront cache‑policy customization is needed for index.html.
Security Considerations¶
| Concern | Action (User) |
|---|---|
| Private access | Keep bucket private; use CloudFront + OAC |
| Least privilege | Scope ListBucket with s3:prefix; Get/Put on reports |
| Credentials | Prefer OIDC / short‑lived role assumption in CI |
| OIDC to AWS | Use GitHub OIDC + role assumption (no static keys) |
| Dependency hygiene | (Optional) run pip-audit / bandit in your pipeline |
| Code scanning | (Optional) enable CodeQL or similar |
| Cache correctness | Ensure index/widgets served with no-cache |
Optional Enhancements¶
| Option | Why |
|---|---|
Provenance (add-provenance) |
Supply chain transparency |
| Auto-clean old runs | Control S3 storage cost |
TTL tagging (--ttl-days) |
Drive lifecycle expiration rules |
| SBOM (CycloneDX) | Dependency inventory / compliance |
GitHub Actions Examples¶
Single Job (pytest plugin, OIDC)¶
jobs:
report:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- run: pip install pytest-allure-host allure-pytest
- run: |
pytest --alluredir=allure-results \
--allure-bucket my-allure-reports \
--allure-project payments \
--allure-branch main \
--allure-cloudfront https://reports.example.com
Split Test/Publish Jobs (Artifact Reuse, OIDC)¶
jobs:
tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- run: pip install pytest allure-pytest
- run: pytest --alluredir=allure-results
- uses: actions/upload-artifact@v4
with:
name: allure-results
path: allure-results
publish:
needs: tests
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- run: pip install pytest-allure-host allure-pytest
- uses: actions/download-artifact@v4
with:
name: allure-results
path: allure-results
- run: |
publish-allure --bucket my-allure-reports \
--project payments --branch main \
--cloudfront https://reports.example.com
Matrix Build Example (Multiple Python Versions)¶
jobs:
report:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
strategy:
matrix:
python-version: [3.10, 3.11, 3.12]
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- run: pip install pytest-allure-host allure-pytest
- run: |
pytest --alluredir=allure-results \
--allure-bucket my-allure-reports \
--allure-project payments \
--allure-branch main \
--allure-cloudfront https://reports.example.com
LocalStack Example (for local testing)¶
jobs:
localtest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- run: pip install pytest-allure-host allure-pytest localstack-client
- run: |
export AWS_ACCESS_KEY_ID=test
export AWS_SECRET_ACCESS_KEY=test
export AWS_REGION=us-east-1
export AWS_ENDPOINT_URL=http://localhost:4566
pytest --alluredir=allure-results \
--allure-bucket my-allure-reports \
--allure-project payments \
--allure-branch main \
--allure-cloudfront http://localhost:4566/distribution
For release/versioning and maintainer workflows see CONTRIBUTING.md.
Jenkins Example (Declarative Pipeline)¶
pipeline {
agent any
environment {
AWS_REGION = 'us-east-1'
REPORT_BUCKET = 'my-allure-reports'
PROJECT = 'payments'
BRANCH = 'main'
CF_DOMAIN = 'reports.example.com'
}
stages {
stage('Setup') {
steps {
sh 'python3 -m venv .venv'
sh '. .venv/bin/activate && pip install --upgrade pip pytest-allure-host allure-pytest'
}
}
stage('Preflight') {
steps {
sh '. .venv/bin/activate && publish-allure --bucket ${REPORT_BUCKET} --project ${PROJECT} --branch ${BRANCH} --cloudfront https://${CF_DOMAIN} --check --dry-run || true'
}
}
stage('Test') {
steps {
sh '. .venv/bin/activate && pytest --alluredir=allure-results'
// Optional: archive results between stages
archiveArtifacts artifacts: 'allure-results/**', fingerprint: true, onlyIfSuccessful: true
}
}
stage('Publish') {
steps {
withAWS(region: "${AWS_REGION}", credentials: 'jenkins-oidc-role') {
sh '''
. .venv/bin/activate
publish-allure \
--bucket ${REPORT_BUCKET} \
--project ${PROJECT} \
--branch ${BRANCH} \
--cloudfront https://${CF_DOMAIN} \
--summary-json summary.json
'''
}
}
}
stage('Summary') {
steps {
script {
def summary = readJSON file: 'summary.json'
echo "Run URL: ${summary.run_url}"
echo "Latest URL: ${summary.latest_url}"
}
}
}
}
}