pytest-allure-host 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Allure Hosting Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,305 @@
1
+ Metadata-Version: 2.4
2
+ Name: pytest-allure-host
3
+ Version: 0.1.1
4
+ Summary: Publish Allure static reports to private S3 behind CloudFront with history preservation
5
+ License-Expression: MIT
6
+ License-File: LICENSE
7
+ Keywords: allure,pytest,aws,s3,cloudfront,reporting
8
+ Author: Allure Hosting Maintainers
9
+ Requires-Python: >=3.9,<4.0
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Topic :: Software Development :: Testing
18
+ Classifier: Framework :: Pytest
19
+ Classifier: Development Status :: 3 - Alpha
20
+ Classifier: Operating System :: OS Independent
21
+ Requires-Dist: PyYAML (>=6,<7)
22
+ Requires-Dist: boto3 (>=1.28,<2.0)
23
+ Project-URL: Bug Tracker, https://github.com/darrenrabbs/allurehosting/issues
24
+ Project-URL: Changelog, https://github.com/darrenrabbs/allurehosting/releases
25
+ Project-URL: Documentation, https://github.com/darrenrabbs/allurehosting#readme
26
+ Project-URL: Homepage, https://github.com/darrenrabbs/allurehosting
27
+ Project-URL: Repository, https://github.com/darrenrabbs/allurehosting
28
+ Description-Content-Type: text/markdown
29
+
30
+ # pytest-allure-host
31
+
32
+ ![CI](https://github.com/darrenrabbs/allurehosting/actions/workflows/ci.yml/badge.svg)
33
+ ![CodeQL](https://github.com/darrenrabbs/allurehosting/actions/workflows/codeql.yml/badge.svg)
34
+ ![PyPI - Version](https://img.shields.io/pypi/v/pytest-allure-host.svg)
35
+ ![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)
36
+
37
+ Publish Allure static reports to private S3 behind CloudFront with history preservation and SPA-friendly routing.
38
+
39
+ See `docs/architecture.md` and `.github/copilot-instructions.md` for architecture and design constraints.
40
+
41
+ ## Features
42
+
43
+ - Generate Allure static report from `allure-results`
44
+ - Preserve history by pulling `latest/history` before generation
45
+ - Upload to S3 under `<project>/<branch>/<run_id>/` and update `<project>/<branch>/latest/`
46
+ - Two-phase latest update: upload to `latest_tmp/`, swap into `latest/`, write `LATEST_READY` marker
47
+ - Optional retention: keep only N newest runs (`--max-keep-runs`)
48
+ - Correct caching headers: `index.html` and `widgets/` → `no-cache`; assets → immutable
49
+ - Optional TTL tagging on objects (`--ttl-days`) for S3 lifecycle policies
50
+ - Optional summary JSON output for CI
51
+ - Best-effort manifest at `runs/index.json` with new run metadata
52
+ - Lightweight pointer file `latest.json` (branch root)
53
+ - Human-friendly HTML index at `runs/index.html` for navigating past runs
54
+ - 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
55
+ - Newest run highlighted with a star (★) and soft background
56
+
57
+ ## Requirements
58
+
59
+ - Python 3.9+
60
+ - AWS credentials with S3 access to the target bucket
61
+ - Allure commandline available on PATH (e.g., via Allure CLI or allure-pytest)
62
+
63
+ ## S3 layout and caching
64
+
65
+ - Keys:
66
+ - `s3://<bucket>/<prefix>/<project>/<branch>/<run_id>/...`
67
+ - `s3://<bucket>/<prefix>/<project>/<branch>/latest/...`
68
+ - `s3://<bucket>/<prefix>/<project>/<branch>/runs/index.json` (manifest)
69
+ - `s3://<bucket>/<prefix>/<project>/<branch>/runs/index.html` (HTML index)
70
+ - `s3://<bucket>/<prefix>/<project>/<branch>/latest.json` (pointer)
71
+ - Two-phase swap writes a `LATEST_READY` marker file under `latest/` when ready.
72
+ - Cache-Control:
73
+ - `index.html`: `no-cache`
74
+ - files under `widgets/`: `no-cache`
75
+ - everything else: `public, max-age=31536000, immutable`
76
+
77
+ ## CLI usage
78
+
79
+ Install locally for development:
80
+
81
+ ```bash
82
+ pip install -e .[dev]
83
+ ```
84
+
85
+ Run the publisher after tests generate `allure-results`:
86
+
87
+ ```bash
88
+ publish-allure \
89
+ --bucket your-bucket \
90
+ --prefix reports \
91
+ --project demo \
92
+ --branch main \
93
+ --cloudfront https://reports.example.com \
94
+ --ttl-days 30 \
95
+ --max-keep-runs 10
96
+ ```
97
+
98
+ Flags (CLI):
99
+
100
+ - `--bucket` (required): S3 bucket name
101
+ - `--prefix` (default: `reports`): Root prefix
102
+ - `--project` (required): Project name
103
+ - `--branch` (default: `$GIT_BRANCH` or `main`)
104
+ - `--run-id` (default: `$ALLURE_RUN_ID` or `YYYYMMDD-HHMMSS`)
105
+ - `--cloudfront` (optional; default: `$ALLURE_CLOUDFRONT`)
106
+ - `--results` (default: `allure-results`): Input directory
107
+ - `--report` (default: `allure-report`): Output directory
108
+ - `--ttl-days` (optional): Add `ttl-days=<N>` object tag
109
+ - `--max-keep-runs` (optional): Keep N newest run prefixes, delete older
110
+ - `--summary-json <path>`: Write machine-readable summary
111
+ - `--check`: Preflight validation (AWS access, allure, inputs)
112
+ - `--dry-run`: Print planned prefixes and sample headers, no upload
113
+ - `--s3-endpoint`: Custom S3 endpoint (e.g. `http://localhost:4566` for LocalStack)
114
+
115
+ Environment fallbacks:
116
+
117
+ - `GIT_BRANCH` → `--branch` default
118
+ - `ALLURE_RUN_ID` → `--run-id` default
119
+ - `ALLURE_CLOUDFRONT` → `--cloudfront` default
120
+ - `ALLURE_S3_ENDPOINT` → `--s3-endpoint` default (LocalStack / custom S3)
121
+
122
+ ## Pytest plugin usage
123
+
124
+ Run tests and publish during terminal summary:
125
+
126
+ ```bash
127
+ pytest \
128
+ --allure-bucket your-bucket \
129
+ --allure-prefix reports \
130
+ --allure-project demo \
131
+ --allure-branch main \
132
+ --allure-cloudfront https://reports.example.com \
133
+ --allure-ttl-days 30 \
134
+ --allure-max-keep-runs 10
135
+ ```
136
+
137
+ Flags (pytest):
138
+
139
+ - `--allure-bucket` (required)
140
+ - `--allure-prefix` (default: `reports`)
141
+ - `--allure-project` (required)
142
+ - `--allure-branch` (default: `$GIT_BRANCH` or `main`)
143
+ - `--allure-run-id` (default: `$ALLURE_RUN_ID` or `YYYYMMDD-HHMMSS`)
144
+ - `--allure-cloudfront` (optional; default: `$ALLURE_CLOUDFRONT`)
145
+ - `--allure-ttl-days` (optional)
146
+ - `--allure-max-keep-runs` (optional)
147
+ - `--allure-summary-json <path>` (optional)
148
+ - `--allure-check` / `--allure-dry-run` (optional)
149
+
150
+ ## Preflight and dry-run
151
+
152
+ - `--check`/`--allure-check` verifies:
153
+ - S3 bucket reachability (HeadBucket/List)
154
+ - `allure-results` exists and is non-empty
155
+ - Allure CLI exists on PATH
156
+ - `--dry-run`/`--allure-dry-run` prints planned prefixes and sample headers; no uploads occur.
157
+
158
+ ## Outputs
159
+
160
+ - S3 prefixes: run and latest
161
+ - Optional CDN URLs (if `--cloudfront` provided)
162
+ - `runs/index.json` manifest updated with new run entry
163
+ - `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 ★)
164
+ - `latest.json` pointer to current run (simple machine-readable metadata)
165
+ - Optional `--summary-json` with sizes, file counts, and destination URLs
166
+ - `latest/LATEST_READY` marker indicates the swap is complete
167
+
168
+ ## Security
169
+
170
+ See `SECURITY.md` for how to report vulnerabilities. Never open a public issue containing sensitive details.
171
+
172
+ ## Badges / Status
173
+
174
+ - CI: multi-version test matrix + lint/security
175
+ - CodeQL: static code analysis
176
+
177
+ ## Contributing
178
+
179
+ See `CONTRIBUTING.md` and follow the pre-commit hooks (`pre-commit install`).
180
+
181
+ ## Release
182
+
183
+ Tagged versions (`vX.Y.Z`) are published to PyPI automatically via GitHub OIDC.
184
+
185
+ ## CI examples
186
+
187
+ GitHub Actions (CLI):
188
+
189
+ ```yaml
190
+ jobs:
191
+ tests:
192
+ runs-on: ubuntu-latest
193
+ steps:
194
+ - uses: actions/checkout@v4
195
+ - uses: actions/setup-python@v5
196
+ with: { python-version: "3.11" }
197
+ - run: pip install .[dev]
198
+ - run: pytest -q
199
+ - name: Publish Allure
200
+ env:
201
+ AWS_REGION: us-east-1
202
+ AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
203
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
204
+ GIT_BRANCH: ${{ github.ref_name }}
205
+ run: >-
206
+ publish-allure --bucket $BUCKET --prefix reports --project demo
207
+ --branch "$GIT_BRANCH" --cloudfront https://reports.example.com
208
+ --ttl-days 30 --max-keep-runs 10
209
+ ```
210
+
211
+ Pytest-driven (plugin):
212
+
213
+ ```yaml
214
+ - run: pytest -q \
215
+ --allure-bucket $BUCKET \
216
+ --allure-prefix reports \
217
+ --allure-project demo \
218
+ --allure-branch "$GIT_BRANCH" \
219
+ --allure-cloudfront https://reports.example.com \
220
+ --allure-ttl-days 30 \
221
+ --allure-max-keep-runs 10
222
+ ```
223
+
224
+ ## Troubleshooting
225
+
226
+ - Missing Allure binary: ensure the Allure CLI is installed and on PATH.
227
+ - Access denied: verify AWS credentials and bucket IAM for Put/Get/List/Delete.
228
+ - SPA routing 403/404: configure CloudFront error mapping to `/index.html`.
229
+
230
+ ## Development
231
+
232
+ - Install with Poetry: `poetry install`
233
+ - Run tests: `poetry run pytest -q`
234
+ - Lint (security quick): `poetry run bandit -r pytest_allure_host`
235
+ - Unified lint helper (mirrors CI):
236
+ ```bash
237
+ scripts/lint.sh # check mode (ruff lint+format check, bandit, pip-audit)
238
+ scripts/lint.sh --fix # apply ruff fixes + format
239
+ scripts/lint.sh pre-commit # also run pre-commit hooks on all files
240
+ ```
241
+
242
+ ## Quick local trial (macOS)
243
+
244
+ This section walks you through a minimal end-to-end run locally.
245
+
246
+ 1. Prereqs
247
+
248
+ - AWS credentials configured (via `AWS_PROFILE` or access keys); set `AWS_REGION`.
249
+ - Allure CLI installed on PATH:
250
+ ```bash
251
+ brew install allure
252
+ ```
253
+ - Python deps installed:
254
+ ```bash
255
+ poetry install
256
+ # or
257
+ pip install -e .[dev]
258
+ ```
259
+
260
+ 2. Generate Allure results
261
+
262
+ - Create a tiny test (optional example):
263
+ ```bash
264
+ mkdir -p tests
265
+ cat > tests/test_sample.py <<'PY'
266
+ def test_ok():
267
+ assert True
268
+ PY
269
+ ```
270
+ - Run pytest to emit results:
271
+ ```bash
272
+ poetry run pytest --alluredir=allure-results
273
+ ```
274
+
275
+ 3. Preflight and dry-run
276
+
277
+ ```bash
278
+ poetry run publish-allure \
279
+ --bucket <bucket> \
280
+ --prefix reports \
281
+ --project demo \
282
+ --branch $(git rev-parse --abbrev-ref HEAD) \
283
+ --cloudfront https://<cloudfront_domain> \
284
+ --check \
285
+ --dry-run
286
+ ```
287
+
288
+ 4. Publish
289
+
290
+ ```bash
291
+ poetry run publish-allure \
292
+ --bucket <bucket> \
293
+ --prefix reports \
294
+ --project demo \
295
+ --branch $(git rev-parse --abbrev-ref HEAD) \
296
+ --cloudfront https://<cloudfront_domain> \
297
+ --ttl-days 30 \
298
+ --max-keep-runs 5
299
+ ```
300
+
301
+ 5. Verify
302
+
303
+ - S3: `reports/demo/<branch>/<run_id>/...` and `reports/demo/<branch>/latest/` with `LATEST_READY`.
304
+ - CDN: open printed `run_url` / `latest_url`.
305
+
@@ -0,0 +1,275 @@
1
+ # pytest-allure-host
2
+
3
+ ![CI](https://github.com/darrenrabbs/allurehosting/actions/workflows/ci.yml/badge.svg)
4
+ ![CodeQL](https://github.com/darrenrabbs/allurehosting/actions/workflows/codeql.yml/badge.svg)
5
+ ![PyPI - Version](https://img.shields.io/pypi/v/pytest-allure-host.svg)
6
+ ![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)
7
+
8
+ Publish Allure static reports to private S3 behind CloudFront with history preservation and SPA-friendly routing.
9
+
10
+ See `docs/architecture.md` and `.github/copilot-instructions.md` for architecture and design constraints.
11
+
12
+ ## Features
13
+
14
+ - Generate Allure static report from `allure-results`
15
+ - Preserve history by pulling `latest/history` before generation
16
+ - Upload to S3 under `<project>/<branch>/<run_id>/` and update `<project>/<branch>/latest/`
17
+ - Two-phase latest update: upload to `latest_tmp/`, swap into `latest/`, write `LATEST_READY` marker
18
+ - Optional retention: keep only N newest runs (`--max-keep-runs`)
19
+ - Correct caching headers: `index.html` and `widgets/` → `no-cache`; assets → immutable
20
+ - Optional TTL tagging on objects (`--ttl-days`) for S3 lifecycle policies
21
+ - Optional summary JSON output for CI
22
+ - Best-effort manifest at `runs/index.json` with new run metadata
23
+ - Lightweight pointer file `latest.json` (branch root)
24
+ - Human-friendly HTML index at `runs/index.html` for navigating past runs
25
+ - 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
26
+ - Newest run highlighted with a star (★) and soft background
27
+
28
+ ## Requirements
29
+
30
+ - Python 3.9+
31
+ - AWS credentials with S3 access to the target bucket
32
+ - Allure commandline available on PATH (e.g., via Allure CLI or allure-pytest)
33
+
34
+ ## S3 layout and caching
35
+
36
+ - Keys:
37
+ - `s3://<bucket>/<prefix>/<project>/<branch>/<run_id>/...`
38
+ - `s3://<bucket>/<prefix>/<project>/<branch>/latest/...`
39
+ - `s3://<bucket>/<prefix>/<project>/<branch>/runs/index.json` (manifest)
40
+ - `s3://<bucket>/<prefix>/<project>/<branch>/runs/index.html` (HTML index)
41
+ - `s3://<bucket>/<prefix>/<project>/<branch>/latest.json` (pointer)
42
+ - Two-phase swap writes a `LATEST_READY` marker file under `latest/` when ready.
43
+ - Cache-Control:
44
+ - `index.html`: `no-cache`
45
+ - files under `widgets/`: `no-cache`
46
+ - everything else: `public, max-age=31536000, immutable`
47
+
48
+ ## CLI usage
49
+
50
+ Install locally for development:
51
+
52
+ ```bash
53
+ pip install -e .[dev]
54
+ ```
55
+
56
+ Run the publisher after tests generate `allure-results`:
57
+
58
+ ```bash
59
+ publish-allure \
60
+ --bucket your-bucket \
61
+ --prefix reports \
62
+ --project demo \
63
+ --branch main \
64
+ --cloudfront https://reports.example.com \
65
+ --ttl-days 30 \
66
+ --max-keep-runs 10
67
+ ```
68
+
69
+ Flags (CLI):
70
+
71
+ - `--bucket` (required): S3 bucket name
72
+ - `--prefix` (default: `reports`): Root prefix
73
+ - `--project` (required): Project name
74
+ - `--branch` (default: `$GIT_BRANCH` or `main`)
75
+ - `--run-id` (default: `$ALLURE_RUN_ID` or `YYYYMMDD-HHMMSS`)
76
+ - `--cloudfront` (optional; default: `$ALLURE_CLOUDFRONT`)
77
+ - `--results` (default: `allure-results`): Input directory
78
+ - `--report` (default: `allure-report`): Output directory
79
+ - `--ttl-days` (optional): Add `ttl-days=<N>` object tag
80
+ - `--max-keep-runs` (optional): Keep N newest run prefixes, delete older
81
+ - `--summary-json <path>`: Write machine-readable summary
82
+ - `--check`: Preflight validation (AWS access, allure, inputs)
83
+ - `--dry-run`: Print planned prefixes and sample headers, no upload
84
+ - `--s3-endpoint`: Custom S3 endpoint (e.g. `http://localhost:4566` for LocalStack)
85
+
86
+ Environment fallbacks:
87
+
88
+ - `GIT_BRANCH` → `--branch` default
89
+ - `ALLURE_RUN_ID` → `--run-id` default
90
+ - `ALLURE_CLOUDFRONT` → `--cloudfront` default
91
+ - `ALLURE_S3_ENDPOINT` → `--s3-endpoint` default (LocalStack / custom S3)
92
+
93
+ ## Pytest plugin usage
94
+
95
+ Run tests and publish during terminal summary:
96
+
97
+ ```bash
98
+ pytest \
99
+ --allure-bucket your-bucket \
100
+ --allure-prefix reports \
101
+ --allure-project demo \
102
+ --allure-branch main \
103
+ --allure-cloudfront https://reports.example.com \
104
+ --allure-ttl-days 30 \
105
+ --allure-max-keep-runs 10
106
+ ```
107
+
108
+ Flags (pytest):
109
+
110
+ - `--allure-bucket` (required)
111
+ - `--allure-prefix` (default: `reports`)
112
+ - `--allure-project` (required)
113
+ - `--allure-branch` (default: `$GIT_BRANCH` or `main`)
114
+ - `--allure-run-id` (default: `$ALLURE_RUN_ID` or `YYYYMMDD-HHMMSS`)
115
+ - `--allure-cloudfront` (optional; default: `$ALLURE_CLOUDFRONT`)
116
+ - `--allure-ttl-days` (optional)
117
+ - `--allure-max-keep-runs` (optional)
118
+ - `--allure-summary-json <path>` (optional)
119
+ - `--allure-check` / `--allure-dry-run` (optional)
120
+
121
+ ## Preflight and dry-run
122
+
123
+ - `--check`/`--allure-check` verifies:
124
+ - S3 bucket reachability (HeadBucket/List)
125
+ - `allure-results` exists and is non-empty
126
+ - Allure CLI exists on PATH
127
+ - `--dry-run`/`--allure-dry-run` prints planned prefixes and sample headers; no uploads occur.
128
+
129
+ ## Outputs
130
+
131
+ - S3 prefixes: run and latest
132
+ - Optional CDN URLs (if `--cloudfront` provided)
133
+ - `runs/index.json` manifest updated with new run entry
134
+ - `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 ★)
135
+ - `latest.json` pointer to current run (simple machine-readable metadata)
136
+ - Optional `--summary-json` with sizes, file counts, and destination URLs
137
+ - `latest/LATEST_READY` marker indicates the swap is complete
138
+
139
+ ## Security
140
+
141
+ See `SECURITY.md` for how to report vulnerabilities. Never open a public issue containing sensitive details.
142
+
143
+ ## Badges / Status
144
+
145
+ - CI: multi-version test matrix + lint/security
146
+ - CodeQL: static code analysis
147
+
148
+ ## Contributing
149
+
150
+ See `CONTRIBUTING.md` and follow the pre-commit hooks (`pre-commit install`).
151
+
152
+ ## Release
153
+
154
+ Tagged versions (`vX.Y.Z`) are published to PyPI automatically via GitHub OIDC.
155
+
156
+ ## CI examples
157
+
158
+ GitHub Actions (CLI):
159
+
160
+ ```yaml
161
+ jobs:
162
+ tests:
163
+ runs-on: ubuntu-latest
164
+ steps:
165
+ - uses: actions/checkout@v4
166
+ - uses: actions/setup-python@v5
167
+ with: { python-version: "3.11" }
168
+ - run: pip install .[dev]
169
+ - run: pytest -q
170
+ - name: Publish Allure
171
+ env:
172
+ AWS_REGION: us-east-1
173
+ AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
174
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
175
+ GIT_BRANCH: ${{ github.ref_name }}
176
+ run: >-
177
+ publish-allure --bucket $BUCKET --prefix reports --project demo
178
+ --branch "$GIT_BRANCH" --cloudfront https://reports.example.com
179
+ --ttl-days 30 --max-keep-runs 10
180
+ ```
181
+
182
+ Pytest-driven (plugin):
183
+
184
+ ```yaml
185
+ - run: pytest -q \
186
+ --allure-bucket $BUCKET \
187
+ --allure-prefix reports \
188
+ --allure-project demo \
189
+ --allure-branch "$GIT_BRANCH" \
190
+ --allure-cloudfront https://reports.example.com \
191
+ --allure-ttl-days 30 \
192
+ --allure-max-keep-runs 10
193
+ ```
194
+
195
+ ## Troubleshooting
196
+
197
+ - Missing Allure binary: ensure the Allure CLI is installed and on PATH.
198
+ - Access denied: verify AWS credentials and bucket IAM for Put/Get/List/Delete.
199
+ - SPA routing 403/404: configure CloudFront error mapping to `/index.html`.
200
+
201
+ ## Development
202
+
203
+ - Install with Poetry: `poetry install`
204
+ - Run tests: `poetry run pytest -q`
205
+ - Lint (security quick): `poetry run bandit -r pytest_allure_host`
206
+ - Unified lint helper (mirrors CI):
207
+ ```bash
208
+ scripts/lint.sh # check mode (ruff lint+format check, bandit, pip-audit)
209
+ scripts/lint.sh --fix # apply ruff fixes + format
210
+ scripts/lint.sh pre-commit # also run pre-commit hooks on all files
211
+ ```
212
+
213
+ ## Quick local trial (macOS)
214
+
215
+ This section walks you through a minimal end-to-end run locally.
216
+
217
+ 1. Prereqs
218
+
219
+ - AWS credentials configured (via `AWS_PROFILE` or access keys); set `AWS_REGION`.
220
+ - Allure CLI installed on PATH:
221
+ ```bash
222
+ brew install allure
223
+ ```
224
+ - Python deps installed:
225
+ ```bash
226
+ poetry install
227
+ # or
228
+ pip install -e .[dev]
229
+ ```
230
+
231
+ 2. Generate Allure results
232
+
233
+ - Create a tiny test (optional example):
234
+ ```bash
235
+ mkdir -p tests
236
+ cat > tests/test_sample.py <<'PY'
237
+ def test_ok():
238
+ assert True
239
+ PY
240
+ ```
241
+ - Run pytest to emit results:
242
+ ```bash
243
+ poetry run pytest --alluredir=allure-results
244
+ ```
245
+
246
+ 3. Preflight and dry-run
247
+
248
+ ```bash
249
+ poetry run publish-allure \
250
+ --bucket <bucket> \
251
+ --prefix reports \
252
+ --project demo \
253
+ --branch $(git rev-parse --abbrev-ref HEAD) \
254
+ --cloudfront https://<cloudfront_domain> \
255
+ --check \
256
+ --dry-run
257
+ ```
258
+
259
+ 4. Publish
260
+
261
+ ```bash
262
+ poetry run publish-allure \
263
+ --bucket <bucket> \
264
+ --prefix reports \
265
+ --project demo \
266
+ --branch $(git rev-parse --abbrev-ref HEAD) \
267
+ --cloudfront https://<cloudfront_domain> \
268
+ --ttl-days 30 \
269
+ --max-keep-runs 5
270
+ ```
271
+
272
+ 5. Verify
273
+
274
+ - S3: `reports/demo/<branch>/<run_id>/...` and `reports/demo/<branch>/latest/` with `LATEST_READY`.
275
+ - CDN: open printed `run_url` / `latest_url`.
@@ -0,0 +1,93 @@
1
+ [build-system]
2
+ requires = ["poetry-core>=1.9.0"]
3
+ build-backend = "poetry.core.masonry.api"
4
+
5
+ [project]
6
+ name = "pytest-allure-host"
7
+ version = "0.1.1"
8
+ description = "Publish Allure static reports to private S3 behind CloudFront with history preservation"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ authors = [ { name = "Allure Hosting Maintainers" } ]
12
+ requires-python = ">=3.9,<4.0"
13
+ keywords = ["allure", "pytest", "aws", "s3", "cloudfront", "reporting"]
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "Programming Language :: Python :: 3.9",
17
+ "Programming Language :: Python :: 3.10",
18
+ "Programming Language :: Python :: 3.11",
19
+ "Programming Language :: Python :: 3.12",
20
+ "Programming Language :: Python :: 3.13",
21
+ "Intended Audience :: Developers",
22
+ "Topic :: Software Development :: Testing",
23
+ "Framework :: Pytest",
24
+ "Development Status :: 3 - Alpha",
25
+ "Operating System :: OS Independent"
26
+ ]
27
+
28
+ dependencies = [
29
+ "boto3>=1.28,<2.0",
30
+ "PyYAML>=6,<7"
31
+ ]
32
+
33
+ [project.optional-dependencies]
34
+ # (Reserved for runtime extras; dev tooling now uses a Poetry dependency group below.)
35
+
36
+ [tool.poetry.group.dev]
37
+ optional = true
38
+
39
+ [tool.poetry.group.dev.dependencies]
40
+ pytest = ">=7,<9"
41
+ moto = {version = ">=5,<6", extras=["s3"]}
42
+ bandit = ">=1.7,<2.0"
43
+ allure-pytest = ">=2,<3"
44
+ pytest-cov = ">=4,<5"
45
+ ruff = ">=0.5,<1.0"
46
+ pip-audit = ">=2.7,<3.0"
47
+ black = ">=24,<25"
48
+
49
+ [project.scripts]
50
+ publish-allure = "pytest_allure_host.cli:main"
51
+
52
+ [project.entry-points."pytest11"]
53
+ pytest_allure_host = "pytest_allure_host.plugin"
54
+
55
+ [project.urls]
56
+ Homepage = "https://github.com/darrenrabbs/allurehosting"
57
+ Repository = "https://github.com/darrenrabbs/allurehosting"
58
+ Documentation = "https://github.com/darrenrabbs/allurehosting#readme"
59
+ "Bug Tracker" = "https://github.com/darrenrabbs/allurehosting/issues"
60
+ Changelog = "https://github.com/darrenrabbs/allurehosting/releases"
61
+
62
+ # Package include (PEP 621 doesn't specify this; still handled by Poetry configuration)
63
+ [tool.poetry]
64
+ packages = [{ include = "pytest_allure_host" }]
65
+ # PEP 621 is authoritative; legacy duplicate metadata removed (require Poetry 2.2.1+)
66
+
67
+ [tool.poetry.dependencies]
68
+ # Retained only for Poetry's internal processing of the runtime dependency group.
69
+ python = ">=3.9,<4.0"
70
+
71
+
72
+ [tool.ruff]
73
+ line-length = 100
74
+ target-version = "py39"
75
+
76
+ [tool.ruff.lint]
77
+ select = ["E", "F", "I", "B", "UP", "S", "W", "C90"]
78
+ ignore = ["E203", "E501"]
79
+
80
+ [tool.ruff.lint.per-file-ignores]
81
+ "tests/**" = ["S101"] # allow bare asserts in test modules
82
+
83
+ [tool.ruff.format]
84
+ quote-style = "double"
85
+ indent-style = "space"
86
+ skip-magic-trailing-comma = false
87
+ line-ending = "lf"
88
+
89
+ [tool.black]
90
+ line-length = 100
91
+ target-version = ["py39"]
92
+ skip-string-normalization = false
93
+ color = true
@@ -0,0 +1,6 @@
1
+ from .utils import PublishConfig, default_run_id # re-export key types
2
+
3
+ __all__ = [
4
+ "PublishConfig",
5
+ "default_run_id",
6
+ ]