proofrun 0.1.1__tar.gz → 0.2.0__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.
- proofrun-0.2.0/.dockerignore +13 -0
- {proofrun-0.1.1 → proofrun-0.2.0}/.github/workflows/ci.yaml +32 -14
- proofrun-0.2.0/.github/workflows/release.yaml +175 -0
- {proofrun-0.1.1 → proofrun-0.2.0}/.gitignore +4 -0
- proofrun-0.2.0/CHANGELOG.md +116 -0
- proofrun-0.2.0/Dockerfile +31 -0
- proofrun-0.2.0/Makefile +89 -0
- proofrun-0.2.0/PKG-INFO +702 -0
- proofrun-0.2.0/README.md +670 -0
- proofrun-0.2.0/deploy/docker-compose.yaml +31 -0
- proofrun-0.2.0/deploy/systemd/proofrun.env.example +13 -0
- proofrun-0.2.0/deploy/systemd/proofrun.service +57 -0
- {proofrun-0.1.1 → proofrun-0.2.0}/pyproject.toml +22 -4
- {proofrun-0.1.1 → proofrun-0.2.0}/scenarios/chain.yaml +2 -2
- {proofrun-0.1.1 → proofrun-0.2.0}/scenarios/crud.yaml +3 -4
- {proofrun-0.1.1 → proofrun-0.2.0}/scenarios/profile.yaml +2 -2
- proofrun-0.2.0/scenarios/resilient.yaml +51 -0
- proofrun-0.2.0/scenarios/server.py +186 -0
- {proofrun-0.1.1 → proofrun-0.2.0}/src/proofrun/__init__.py +1 -1
- {proofrun-0.1.1 → proofrun-0.2.0}/src/proofrun/__main__.py +1 -1
- proofrun-0.2.0/src/proofrun/cli/__init__.py +5 -0
- proofrun-0.2.0/src/proofrun/cli/commands.py +392 -0
- proofrun-0.2.0/src/proofrun/cli/render.py +97 -0
- proofrun-0.2.0/src/proofrun/config/__init__.py +1 -0
- {proofrun-0.1.1/src/proofrun/core → proofrun-0.2.0/src/proofrun/config}/compiler.py +62 -4
- proofrun-0.2.0/src/proofrun/config/envvars.py +75 -0
- proofrun-0.1.1/src/proofrun/core/config.py → proofrun-0.2.0/src/proofrun/config/models.py +96 -8
- {proofrun-0.1.1/src/proofrun/core → proofrun-0.2.0/src/proofrun/config}/provider.py +14 -3
- proofrun-0.1.1/src/proofrun/core/state.py → proofrun-0.2.0/src/proofrun/health.py +23 -3
- proofrun-0.2.0/src/proofrun/metrics/__init__.py +1 -0
- proofrun-0.2.0/src/proofrun/metrics/registry.py +136 -0
- proofrun-0.2.0/src/proofrun/metrics/server.py +117 -0
- proofrun-0.2.0/src/proofrun/monitor/__init__.py +1 -0
- proofrun-0.2.0/src/proofrun/monitor/daemon.py +202 -0
- proofrun-0.2.0/src/proofrun/monitor/scheduler.py +75 -0
- proofrun-0.2.0/src/proofrun/notify/__init__.py +1 -0
- proofrun-0.2.0/src/proofrun/notify/base.py +26 -0
- proofrun-0.1.1/src/proofrun/core/notifier.py → proofrun-0.2.0/src/proofrun/notify/webhook.py +25 -19
- proofrun-0.2.0/src/proofrun/runner/__init__.py +1 -0
- {proofrun-0.1.1/src/proofrun/core → proofrun-0.2.0/src/proofrun/runner}/context.py +16 -6
- {proofrun-0.1.1/src/proofrun/core → proofrun-0.2.0/src/proofrun/runner}/engine.py +48 -4
- proofrun-0.2.0/src/proofrun/runner/execution.py +56 -0
- proofrun-0.2.0/tests/conftest.py +45 -0
- proofrun-0.2.0/tests/test_cli.py +687 -0
- {proofrun-0.1.1 → proofrun-0.2.0}/tests/test_compiler.py +319 -2
- {proofrun-0.1.1 → proofrun-0.2.0}/tests/test_config.py +162 -3
- {proofrun-0.1.1 → proofrun-0.2.0}/tests/test_context.py +34 -1
- proofrun-0.2.0/tests/test_daemon.py +571 -0
- {proofrun-0.1.1 → proofrun-0.2.0}/tests/test_engine.py +89 -3
- proofrun-0.2.0/tests/test_envvars.py +69 -0
- proofrun-0.2.0/tests/test_execution.py +128 -0
- proofrun-0.1.1/tests/test_state.py → proofrun-0.2.0/tests/test_health.py +75 -1
- {proofrun-0.1.1 → proofrun-0.2.0}/tests/test_main.py +2 -2
- proofrun-0.2.0/tests/test_metrics.py +246 -0
- {proofrun-0.1.1 → proofrun-0.2.0}/tests/test_notifier.py +82 -13
- {proofrun-0.1.1 → proofrun-0.2.0}/tests/test_provider.py +49 -2
- proofrun-0.2.0/tests/test_readme.py +38 -0
- proofrun-0.2.0/tests/test_scheduler.py +95 -0
- {proofrun-0.1.1 → proofrun-0.2.0}/uv.lock +5 -70
- proofrun-0.1.1/.github/workflows/release.yaml +0 -113
- proofrun-0.1.1/Makefile +0 -67
- proofrun-0.1.1/PKG-INFO +0 -268
- proofrun-0.1.1/README.md +0 -250
- proofrun-0.1.1/scenarios/server.py +0 -83
- proofrun-0.1.1/src/proofrun/cli.py +0 -325
- proofrun-0.1.1/src/proofrun/core/__init__.py +0 -40
- proofrun-0.1.1/tests/test_cli.py +0 -912
- {proofrun-0.1.1 → proofrun-0.2.0}/.pre-commit-config.yaml +0 -0
- {proofrun-0.1.1 → proofrun-0.2.0}/LICENSE +0 -0
- {proofrun-0.1.1 → proofrun-0.2.0}/docs/demo-fail.svg +0 -0
- {proofrun-0.1.1 → proofrun-0.2.0}/docs/demo-pass.svg +0 -0
- {proofrun-0.1.1 → proofrun-0.2.0}/scenarios/auth.yaml +0 -0
- {proofrun-0.1.1 → proofrun-0.2.0}/tests/__init__.py +0 -0
|
@@ -16,7 +16,7 @@ permissions:
|
|
|
16
16
|
jobs:
|
|
17
17
|
quality:
|
|
18
18
|
name: Quality & Tests
|
|
19
|
-
runs-on: ubuntu-
|
|
19
|
+
runs-on: ubuntu-24.04
|
|
20
20
|
|
|
21
21
|
strategy:
|
|
22
22
|
fail-fast: false
|
|
@@ -27,15 +27,15 @@ jobs:
|
|
|
27
27
|
|
|
28
28
|
steps:
|
|
29
29
|
- name: Checkout repository
|
|
30
|
-
uses: actions/checkout@
|
|
30
|
+
uses: actions/checkout@v7
|
|
31
31
|
|
|
32
32
|
- name: Set up Python
|
|
33
|
-
uses: actions/setup-python@
|
|
33
|
+
uses: actions/setup-python@v7
|
|
34
34
|
with:
|
|
35
35
|
python-version: ${{ matrix.python-version }}
|
|
36
36
|
|
|
37
37
|
- name: Set up uv
|
|
38
|
-
uses: astral-sh/setup-uv@
|
|
38
|
+
uses: astral-sh/setup-uv@v7
|
|
39
39
|
with:
|
|
40
40
|
enable-cache: true
|
|
41
41
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -46,29 +46,25 @@ jobs:
|
|
|
46
46
|
- name: Run code quality & coverage checks
|
|
47
47
|
run: make check
|
|
48
48
|
|
|
49
|
-
- name: Run integration scenarios
|
|
50
|
-
run:
|
|
51
|
-
make run-profile
|
|
52
|
-
make run-auth
|
|
53
|
-
make run-chain
|
|
54
|
-
make run-crud
|
|
49
|
+
- name: Run integration scenarios (local demo API, no network)
|
|
50
|
+
run: make integration
|
|
55
51
|
|
|
56
52
|
build:
|
|
57
53
|
name: Build Package
|
|
58
|
-
runs-on: ubuntu-
|
|
54
|
+
runs-on: ubuntu-24.04
|
|
59
55
|
needs: quality
|
|
60
56
|
|
|
61
57
|
steps:
|
|
62
58
|
- name: Checkout repository
|
|
63
|
-
uses: actions/checkout@
|
|
59
|
+
uses: actions/checkout@v7
|
|
64
60
|
|
|
65
61
|
- name: Set up Python
|
|
66
|
-
uses: actions/setup-python@
|
|
62
|
+
uses: actions/setup-python@v7
|
|
67
63
|
with:
|
|
68
64
|
python-version: "3.11"
|
|
69
65
|
|
|
70
66
|
- name: Set up uv
|
|
71
|
-
uses: astral-sh/setup-uv@
|
|
67
|
+
uses: astral-sh/setup-uv@v7
|
|
72
68
|
with:
|
|
73
69
|
enable-cache: true
|
|
74
70
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -84,3 +80,25 @@ jobs:
|
|
|
84
80
|
ls -lh dist/
|
|
85
81
|
test -f dist/*.whl
|
|
86
82
|
test -f dist/*.tar.gz
|
|
83
|
+
|
|
84
|
+
- name: Install the built packages in a clean environment
|
|
85
|
+
run: make dist-smoke
|
|
86
|
+
|
|
87
|
+
docker:
|
|
88
|
+
name: Docker Image
|
|
89
|
+
runs-on: ubuntu-24.04
|
|
90
|
+
needs: quality
|
|
91
|
+
|
|
92
|
+
steps:
|
|
93
|
+
- name: Checkout repository
|
|
94
|
+
uses: actions/checkout@v7
|
|
95
|
+
|
|
96
|
+
- name: Build image
|
|
97
|
+
run: docker build --tag proofrun:ci .
|
|
98
|
+
|
|
99
|
+
- name: Smoke test image
|
|
100
|
+
run: |
|
|
101
|
+
docker run --rm proofrun:ci --version
|
|
102
|
+
docker run --rm -v "$PWD/scenarios:/monitors:ro" \
|
|
103
|
+
-e DEMO_PASSWORD=demo-password \
|
|
104
|
+
proofrun:ci /monitors/resilient.yaml --validate
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
quality:
|
|
13
|
+
name: Quality & Tests
|
|
14
|
+
runs-on: ubuntu-24.04
|
|
15
|
+
steps:
|
|
16
|
+
- name: Checkout repository
|
|
17
|
+
uses: actions/checkout@v7
|
|
18
|
+
|
|
19
|
+
- name: Set up Python
|
|
20
|
+
uses: actions/setup-python@v7
|
|
21
|
+
with:
|
|
22
|
+
python-version: "3.11"
|
|
23
|
+
|
|
24
|
+
- name: Set up uv
|
|
25
|
+
uses: astral-sh/setup-uv@v7
|
|
26
|
+
with:
|
|
27
|
+
enable-cache: true
|
|
28
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
29
|
+
|
|
30
|
+
- name: Install dependencies
|
|
31
|
+
run: make install
|
|
32
|
+
|
|
33
|
+
- name: Run code quality checks
|
|
34
|
+
run: make check
|
|
35
|
+
|
|
36
|
+
- name: Run integration scenarios (local demo API, no network)
|
|
37
|
+
run: make integration
|
|
38
|
+
|
|
39
|
+
build:
|
|
40
|
+
name: Build Package
|
|
41
|
+
runs-on: ubuntu-24.04
|
|
42
|
+
needs: quality
|
|
43
|
+
steps:
|
|
44
|
+
- name: Checkout repository
|
|
45
|
+
uses: actions/checkout@v7
|
|
46
|
+
|
|
47
|
+
- name: Set up Python
|
|
48
|
+
uses: actions/setup-python@v7
|
|
49
|
+
with:
|
|
50
|
+
python-version: "3.11"
|
|
51
|
+
|
|
52
|
+
- name: Set up uv
|
|
53
|
+
uses: astral-sh/setup-uv@v7
|
|
54
|
+
with:
|
|
55
|
+
enable-cache: true
|
|
56
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
57
|
+
|
|
58
|
+
- name: Verify tag matches package version
|
|
59
|
+
run: |
|
|
60
|
+
TAG_VERSION="${GITHUB_REF_NAME#v}"
|
|
61
|
+
PKG_VERSION="$(grep -m1 '^version = ' pyproject.toml | cut -d'"' -f2)"
|
|
62
|
+
echo "tag: ${TAG_VERSION} pyproject: ${PKG_VERSION}"
|
|
63
|
+
if [ "${TAG_VERSION}" != "${PKG_VERSION}" ]; then
|
|
64
|
+
echo "::error::Tag v${TAG_VERSION} does not match pyproject version ${PKG_VERSION}"
|
|
65
|
+
exit 1
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
- name: Build distributions
|
|
69
|
+
run: make build
|
|
70
|
+
|
|
71
|
+
- name: Install the built packages in a clean environment
|
|
72
|
+
run: make dist-smoke
|
|
73
|
+
|
|
74
|
+
- name: Store distributions
|
|
75
|
+
uses: actions/upload-artifact@v7
|
|
76
|
+
with:
|
|
77
|
+
name: package-distributions
|
|
78
|
+
path: dist/
|
|
79
|
+
|
|
80
|
+
publish-to-pypi:
|
|
81
|
+
name: Publish to PyPI
|
|
82
|
+
runs-on: ubuntu-24.04
|
|
83
|
+
needs: build
|
|
84
|
+
environment: release
|
|
85
|
+
permissions:
|
|
86
|
+
id-token: write
|
|
87
|
+
steps:
|
|
88
|
+
- name: Download distributions
|
|
89
|
+
uses: actions/download-artifact@v8
|
|
90
|
+
with:
|
|
91
|
+
name: package-distributions
|
|
92
|
+
path: dist/
|
|
93
|
+
|
|
94
|
+
- name: Publish to PyPI
|
|
95
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
96
|
+
|
|
97
|
+
publish-docker:
|
|
98
|
+
name: Publish Docker Image
|
|
99
|
+
runs-on: ubuntu-24.04
|
|
100
|
+
needs: build
|
|
101
|
+
permissions:
|
|
102
|
+
contents: read
|
|
103
|
+
packages: write
|
|
104
|
+
steps:
|
|
105
|
+
- name: Checkout repository
|
|
106
|
+
uses: actions/checkout@v7
|
|
107
|
+
|
|
108
|
+
- name: Set up QEMU
|
|
109
|
+
uses: docker/setup-qemu-action@v4
|
|
110
|
+
|
|
111
|
+
- name: Set up Docker Buildx
|
|
112
|
+
uses: docker/setup-buildx-action@v4
|
|
113
|
+
|
|
114
|
+
- name: Build image for smoke test
|
|
115
|
+
uses: docker/build-push-action@v7
|
|
116
|
+
with:
|
|
117
|
+
context: .
|
|
118
|
+
load: true
|
|
119
|
+
tags: proofrun:smoke
|
|
120
|
+
cache-from: type=gha
|
|
121
|
+
cache-to: type=gha,mode=max
|
|
122
|
+
|
|
123
|
+
- name: Smoke test image
|
|
124
|
+
run: |
|
|
125
|
+
TAG_VERSION="${GITHUB_REF_NAME#v}"
|
|
126
|
+
OUTPUT="$(docker run --rm proofrun:smoke --version)"
|
|
127
|
+
echo "${OUTPUT}"
|
|
128
|
+
echo "${OUTPUT}" | grep -qxF "Proofrun version ${TAG_VERSION}"
|
|
129
|
+
|
|
130
|
+
- name: Log in to GitHub Container Registry
|
|
131
|
+
uses: docker/login-action@v4
|
|
132
|
+
with:
|
|
133
|
+
registry: ghcr.io
|
|
134
|
+
username: ${{ github.actor }}
|
|
135
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
136
|
+
|
|
137
|
+
- name: Generate image tags and labels
|
|
138
|
+
id: meta
|
|
139
|
+
uses: docker/metadata-action@v6
|
|
140
|
+
with:
|
|
141
|
+
images: ghcr.io/kishan-thanki/proofrun
|
|
142
|
+
tags: |
|
|
143
|
+
type=semver,pattern={{version}}
|
|
144
|
+
type=semver,pattern={{major}}.{{minor}}
|
|
145
|
+
type=raw,value=latest,enable=${{ !contains(github.ref_name, '-') }}
|
|
146
|
+
|
|
147
|
+
- name: Build and push (linux/amd64, linux/arm64)
|
|
148
|
+
uses: docker/build-push-action@v7
|
|
149
|
+
with:
|
|
150
|
+
context: .
|
|
151
|
+
platforms: linux/amd64,linux/arm64
|
|
152
|
+
push: true
|
|
153
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
154
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
155
|
+
cache-from: type=gha
|
|
156
|
+
cache-to: type=gha,mode=max
|
|
157
|
+
|
|
158
|
+
github-release:
|
|
159
|
+
name: Create GitHub Release
|
|
160
|
+
runs-on: ubuntu-24.04
|
|
161
|
+
needs: [publish-to-pypi, publish-docker]
|
|
162
|
+
permissions:
|
|
163
|
+
contents: write
|
|
164
|
+
steps:
|
|
165
|
+
- name: Download distributions
|
|
166
|
+
uses: actions/download-artifact@v8
|
|
167
|
+
with:
|
|
168
|
+
name: package-distributions
|
|
169
|
+
path: dist/
|
|
170
|
+
|
|
171
|
+
- name: Create GitHub Release
|
|
172
|
+
uses: softprops/action-gh-release@v3
|
|
173
|
+
with:
|
|
174
|
+
files: dist/*
|
|
175
|
+
generate_release_notes: true
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Proofrun are documented here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Proofrun is below 1.0,
|
|
5
|
+
so a minor release can contain breaking changes; each one is listed under
|
|
6
|
+
**Breaking changes**.
|
|
7
|
+
|
|
8
|
+
## [0.2.0]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Environment variables.** `${env.NAME}` is resolved when a config file is
|
|
13
|
+
loaded, in any value or key, including `base_url`. A missing variable is a
|
|
14
|
+
configuration error that names the variable and where it is used.
|
|
15
|
+
- **Retries.** `retries` and `retry_delay_seconds` (per scenario or under
|
|
16
|
+
`global`) re-run the whole scenario before a failure counts. Results show
|
|
17
|
+
`Attempts: N`. Retries also work in run-once mode.
|
|
18
|
+
- **Thresholds.** `failure_threshold` and `recovery_threshold` count consecutive
|
|
19
|
+
runs before a scenario becomes `FAILING` or recovers. The defaults (`1`, `1`)
|
|
20
|
+
keep the previous behavior.
|
|
21
|
+
- **Per-scenario scheduling.** Every scenario runs on its own `interval_seconds`,
|
|
22
|
+
with jitter. A slow scenario does not delay another, and a scenario never
|
|
23
|
+
overlaps with itself. `interval_seconds` can also be set under `global`.
|
|
24
|
+
- **Metrics.** `--metrics-port` (and `--metrics-host`) serve
|
|
25
|
+
`/metrics` and `/health` in daemon mode. Metrics: `proofrun_scenario_up`,
|
|
26
|
+
`_runs_total`, `_failures_total`, `_duration_seconds`,
|
|
27
|
+
`_last_success_timestamp_seconds`, `_last_failure_timestamp_seconds`. The only
|
|
28
|
+
label is `scenario`. The server binds to loopback by default.
|
|
29
|
+
- **`--validate`.** Checks a configuration, including environment references,
|
|
30
|
+
without sending requests.
|
|
31
|
+
- **Docker image** for `linux/amd64` and `linux/arm64`, published to
|
|
32
|
+
`ghcr.io/kishan-thanki/proofrun` by the release pipeline (after the tests pass and
|
|
33
|
+
the tag matches the package version), running as a non-root user.
|
|
34
|
+
- **Deployment examples:** a hardened systemd unit and environment file in
|
|
35
|
+
`deploy/systemd/`, and `deploy/docker-compose.yaml`.
|
|
36
|
+
- `scenarios/resilient.yaml`, an offline example of the features above.
|
|
37
|
+
- A warning when `--webhook-url` or `--metrics-port` is given in run-once mode,
|
|
38
|
+
where they have no effect.
|
|
39
|
+
- Duplicate scenario names and extract variable names starting with `env.` are
|
|
40
|
+
rejected when the config is loaded.
|
|
41
|
+
- PyPI metadata: keywords, classifiers, and project URLs.
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
|
|
45
|
+
- The daemon is now event-driven per scenario instead of running every scenario
|
|
46
|
+
in lockstep. Configuration changes are picked up within about a second.
|
|
47
|
+
- An invalid configuration file is parsed once per change and its error is
|
|
48
|
+
printed once, instead of on every cycle.
|
|
49
|
+
- Configuration validation errors show the field location and message without
|
|
50
|
+
echoing the offending input, so resolved secrets cannot leak.
|
|
51
|
+
- Rich markup in scenario names, step names, and error text is escaped.
|
|
52
|
+
- `uvloop` is installed only where it is available (not on Windows), and Proofrun
|
|
53
|
+
falls back to the standard `asyncio` loop. `orjson`, which was never used, is no
|
|
54
|
+
longer a dependency. The minimum `pydantic` is now 2.7.
|
|
55
|
+
- The source is organized into packages by concern (`cli`, `config`, `runner`,
|
|
56
|
+
`monitor`, `notify`, `metrics`, plus `health`) instead of a single `core` package.
|
|
57
|
+
Only files moved; behavior is unchanged.
|
|
58
|
+
- Integration scenarios and the CI and release pipelines run against the local demo
|
|
59
|
+
API (`make integration`), with no dependency on a third-party host.
|
|
60
|
+
|
|
61
|
+
### Fixed
|
|
62
|
+
|
|
63
|
+
- A failed webhook delivery printed the full webhook URL, which often contains a secret
|
|
64
|
+
token, and a timeout printed nothing useful. Failures now report only the reason (an
|
|
65
|
+
HTTP status, a timeout, or a connection error) and the scenario name.
|
|
66
|
+
- The daemon kept running with no valid configuration, looking alive while monitoring
|
|
67
|
+
nothing. An invalid configuration at startup now exits with code 1. An invalid edit
|
|
68
|
+
while running still keeps the last working configuration.
|
|
69
|
+
- The daemon was killed abruptly by `SIGTERM`, and as PID 1 in a container it never
|
|
70
|
+
received the signal, so `docker stop` waited and then killed it. `SIGTERM` now stops
|
|
71
|
+
it cleanly.
|
|
72
|
+
- `expect.status` accepted an empty list and codes outside 100 to 599, which can never
|
|
73
|
+
match a response. Both are now configuration errors.
|
|
74
|
+
- `--interval` and `--metrics-host` were silently ignored in run-once mode. They now
|
|
75
|
+
produce the same warning as `--webhook-url` and `--metrics-port`.
|
|
76
|
+
- A configuration with no scenarios, or a scenario with no steps, used to pass and report
|
|
77
|
+
success without making a request. Both are now configuration errors.
|
|
78
|
+
- Misspelled field names were silently ignored, so the check they were meant to
|
|
79
|
+
configure never ran. Unknown fields are now rejected with their location.
|
|
80
|
+
- Header mismatch errors no longer print the values of sensitive headers (names
|
|
81
|
+
containing auth, cookie, token, secret, key, password, or session), so they cannot
|
|
82
|
+
reach the console or webhook alerts.
|
|
83
|
+
- Dictionary keys that interpolate to the same name now fail the step instead of
|
|
84
|
+
silently dropping one of them.
|
|
85
|
+
- Scenarios that ran at the same time shared one HTTP client, so a run could clear
|
|
86
|
+
or read another run's cookies. Every run now has its own client.
|
|
87
|
+
- Removed stale `proof` naming (badges, example headers and query values, a hard-coded
|
|
88
|
+
User-Agent version, and the fallback package version).
|
|
89
|
+
|
|
90
|
+
### Breaking changes
|
|
91
|
+
|
|
92
|
+
- **A daemon with an invalid configuration at startup now exits with code 1** instead of
|
|
93
|
+
waiting for the file to be fixed. Under systemd or Docker, a restart policy will keep
|
|
94
|
+
retrying until the file is valid.
|
|
95
|
+
- **Configuration validation is strict.** A file with a misspelled or unknown field, no
|
|
96
|
+
scenarios, or a scenario without steps now fails to load. Run `proofrun --validate`
|
|
97
|
+
on your files before upgrading.
|
|
98
|
+
- **The webhook environment variable is `PROOFRUN_WEBHOOK_URL`.** `PROOF_WEBHOOK_URL`
|
|
99
|
+
is no longer read, and there is no alias. If you set the old name, alerts stop
|
|
100
|
+
until you rename it.
|
|
101
|
+
- **`interval_seconds` is now per scenario.** Before, all scenarios ran together on
|
|
102
|
+
the smallest interval in the file. Scenarios with different intervals now run at
|
|
103
|
+
different rates. `--interval N` still runs everything every N seconds.
|
|
104
|
+
- Configuration validation error text has a new format.
|
|
105
|
+
- `${env.NAME}` is resolved at load time, so a config that contained that literal text
|
|
106
|
+
needs the variable to exist (it would previously have failed at run time).
|
|
107
|
+
- Python imports changed. `proofrun.core` no longer exists; for example
|
|
108
|
+
`proofrun.core.daemon.Daemon` is now `proofrun.monitor.daemon.Daemon`, and
|
|
109
|
+
`proofrun.cli.execute_config` is replaced by `run_once` in `proofrun.cli.commands`.
|
|
110
|
+
The command line is the supported interface; there is no stable Python API yet.
|
|
111
|
+
|
|
112
|
+
## [0.1.1]
|
|
113
|
+
|
|
114
|
+
Initial public release: YAML scenarios, multi-step requests with JSONPath
|
|
115
|
+
extraction, status, latency, header, and JSON Schema assertions, run-once and
|
|
116
|
+
daemon modes, webhook alerts on health changes, and hot configuration reload.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# syntax=docker/dockerfile:1
|
|
2
|
+
|
|
3
|
+
FROM python:3.12.15-alpine AS build
|
|
4
|
+
|
|
5
|
+
RUN apk upgrade --no-cache
|
|
6
|
+
|
|
7
|
+
ENV PIP_DISABLE_PIP_VERSION_CHECK=1 \
|
|
8
|
+
PIP_NO_CACHE_DIR=1
|
|
9
|
+
|
|
10
|
+
WORKDIR /src
|
|
11
|
+
COPY pyproject.toml README.md LICENSE ./
|
|
12
|
+
COPY src ./src
|
|
13
|
+
|
|
14
|
+
RUN python -m venv /opt/venv \
|
|
15
|
+
&& /opt/venv/bin/pip install .
|
|
16
|
+
|
|
17
|
+
FROM python:3.12.15-alpine
|
|
18
|
+
|
|
19
|
+
COPY --from=build /opt/venv /opt/venv
|
|
20
|
+
|
|
21
|
+
RUN apk upgrade --no-cache \
|
|
22
|
+
&& adduser -S -D -H -u 10001 -s /bin/false proofrun
|
|
23
|
+
|
|
24
|
+
ENV PATH="/opt/venv/bin:${PATH}" \
|
|
25
|
+
PYTHONUNBUFFERED=1
|
|
26
|
+
|
|
27
|
+
USER proofrun
|
|
28
|
+
WORKDIR /monitors
|
|
29
|
+
|
|
30
|
+
ENTRYPOINT ["proofrun"]
|
|
31
|
+
CMD ["--help"]
|
proofrun-0.2.0/Makefile
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
PYTHON ?= python3
|
|
2
|
+
|
|
3
|
+
.PHONY: install test coverage coverage-html lint format format-check typecheck check \
|
|
4
|
+
serve integration build dist-smoke clean full
|
|
5
|
+
|
|
6
|
+
full: clean install check build
|
|
7
|
+
|
|
8
|
+
install:
|
|
9
|
+
uv sync --group dev
|
|
10
|
+
|
|
11
|
+
test:
|
|
12
|
+
uv run pytest -q
|
|
13
|
+
|
|
14
|
+
coverage:
|
|
15
|
+
uv run pytest -q --cov=proofrun --cov-branch \
|
|
16
|
+
--cov-report=term-missing \
|
|
17
|
+
--cov-fail-under=100
|
|
18
|
+
|
|
19
|
+
coverage-html:
|
|
20
|
+
uv run pytest -q --cov=proofrun --cov-branch \
|
|
21
|
+
--cov-report=html
|
|
22
|
+
@echo "Coverage report generated: htmlcov/index.html"
|
|
23
|
+
|
|
24
|
+
lint:
|
|
25
|
+
uv run ruff check src/ tests/
|
|
26
|
+
|
|
27
|
+
format:
|
|
28
|
+
uv run ruff format src/ tests/
|
|
29
|
+
|
|
30
|
+
format-check:
|
|
31
|
+
uv run ruff format --check src/ tests/
|
|
32
|
+
uv run ruff check src/ tests/
|
|
33
|
+
|
|
34
|
+
typecheck:
|
|
35
|
+
uv run pyright
|
|
36
|
+
|
|
37
|
+
check: lint format-check typecheck coverage
|
|
38
|
+
|
|
39
|
+
serve:
|
|
40
|
+
$(PYTHON) scenarios/server.py
|
|
41
|
+
|
|
42
|
+
integration:
|
|
43
|
+
@$(PYTHON) scenarios/server.py & \
|
|
44
|
+
SERVER_PID=$$!; \
|
|
45
|
+
trap 'kill $$SERVER_PID 2>/dev/null || true' EXIT; \
|
|
46
|
+
up=0; \
|
|
47
|
+
for i in $$(seq 1 50); do \
|
|
48
|
+
$(PYTHON) -c "import urllib.request as u; u.urlopen('http://127.0.0.1:8099/health')" \
|
|
49
|
+
>/dev/null 2>&1 && up=1 && break; \
|
|
50
|
+
sleep 0.2; \
|
|
51
|
+
done; \
|
|
52
|
+
if [ $$up -ne 1 ]; then \
|
|
53
|
+
echo "The demo API did not start on 127.0.0.1:8099. Is '$(PYTHON)' installed and the port free?"; \
|
|
54
|
+
echo "Try: make integration PYTHON=/path/to/python3"; \
|
|
55
|
+
exit 1; \
|
|
56
|
+
fi; \
|
|
57
|
+
export DEMO_PASSWORD=demo-password; \
|
|
58
|
+
status=0; \
|
|
59
|
+
for name in profile auth chain crud resilient; do \
|
|
60
|
+
echo "==> scenarios/$$name.yaml"; \
|
|
61
|
+
uv run proofrun scenarios/$$name.yaml --validate >/dev/null || status=1; \
|
|
62
|
+
uv run proofrun scenarios/$$name.yaml || status=1; \
|
|
63
|
+
done; \
|
|
64
|
+
exit $$status
|
|
65
|
+
|
|
66
|
+
dist-smoke:
|
|
67
|
+
@set -e; tmp=$$(mktemp -d); trap 'rm -rf "$$tmp"' EXIT; \
|
|
68
|
+
for pkg in dist/*.whl dist/*.tar.gz; do \
|
|
69
|
+
echo "==> installing $$pkg in a clean environment"; \
|
|
70
|
+
$(PYTHON) -m venv "$$tmp/venv"; \
|
|
71
|
+
"$$tmp/venv/bin/pip" install --quiet "$$pkg"; \
|
|
72
|
+
"$$tmp/venv/bin/proofrun" --version; \
|
|
73
|
+
DEMO_PASSWORD=smoke "$$tmp/venv/bin/proofrun" scenarios/resilient.yaml --validate >/dev/null; \
|
|
74
|
+
rm -rf "$$tmp/venv"; \
|
|
75
|
+
done
|
|
76
|
+
|
|
77
|
+
build:
|
|
78
|
+
uv build
|
|
79
|
+
|
|
80
|
+
clean:
|
|
81
|
+
rm -rf dist/ \
|
|
82
|
+
.ruff_cache/ \
|
|
83
|
+
.pytest_cache/ \
|
|
84
|
+
.pyright_cache/ \
|
|
85
|
+
.coverage \
|
|
86
|
+
.coverage.* \
|
|
87
|
+
htmlcov/ \
|
|
88
|
+
__pycache__/ \
|
|
89
|
+
*.egg-info/
|