continuo-python-runtime 0.3.0__tar.gz → 0.3.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.
- continuo_python_runtime-0.3.1/.github/CODEOWNERS +2 -0
- continuo_python_runtime-0.3.1/.github/ISSUE_TEMPLATE/bug_report.yml +59 -0
- continuo_python_runtime-0.3.1/.github/ISSUE_TEMPLATE/config.yml +5 -0
- continuo_python_runtime-0.3.1/.github/ISSUE_TEMPLATE/feature_request.yml +30 -0
- continuo_python_runtime-0.3.1/.github/PULL_REQUEST_TEMPLATE.md +20 -0
- continuo_python_runtime-0.3.1/.github/dependabot.yml +64 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/.github/workflows/ci.yml +3 -3
- continuo_python_runtime-0.3.1/.github/workflows/dco.yml +49 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/.github/workflows/images.yml +5 -5
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/.github/workflows/publish-pypi.yml +1 -1
- continuo_python_runtime-0.3.1/.github/workflows/release.yml +141 -0
- continuo_python_runtime-0.3.1/.github/workflows/security.yml +130 -0
- continuo_python_runtime-0.3.1/.gitleaks.toml +36 -0
- continuo_python_runtime-0.3.1/CHANGELOG.md +84 -0
- continuo_python_runtime-0.3.1/CODE_OF_CONDUCT.md +133 -0
- continuo_python_runtime-0.3.1/CONTRIBUTING.md +99 -0
- continuo_python_runtime-0.3.1/DCO +34 -0
- continuo_python_runtime-0.3.1/LICENSE +201 -0
- continuo_python_runtime-0.3.1/NOTICE +11 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/PKG-INFO +11 -4
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/README.md +6 -2
- continuo_python_runtime-0.3.1/SECURITY.md +80 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/adapters/postgres/pyproject.toml +2 -2
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/adapters/trino/pyproject.toml +2 -2
- continuo_python_runtime-0.3.1/contract/LICENSE +201 -0
- continuo_python_runtime-0.3.1/contract/NOTICE +12 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/contract/pyproject.toml +3 -1
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/pyproject.toml +5 -3
- continuo_python_runtime-0.3.1/scripts/security-scan.sh +178 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/template/Dockerfile +1 -1
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/test_no_legacy_names.py +4 -1
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/uv.lock +9 -8
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/.dockerignore +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/.gitignore +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/Dockerfile.postgres +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/Dockerfile.trino +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/adapters/postgres/README.md +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/adapters/postgres/continuo_python_runtime_postgres/__init__.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/adapters/postgres/continuo_python_runtime_postgres/adapter.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/adapters/postgres/tests/__init__.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/adapters/postgres/tests/test_adapter_postgres_validation.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/adapters/postgres/tests/test_adapter_runtime_postgres.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/adapters/postgres/tests/test_integration_postgres_validation.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/adapters/postgres/tests/test_integration_runtime_postgres.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/adapters/trino/README.md +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/adapters/trino/continuo_python_runtime_trino/__init__.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/adapters/trino/continuo_python_runtime_trino/adapter.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/adapters/trino/tests/__init__.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/adapters/trino/tests/test_adapter_runtime_trino.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/adapters/trino/tests/test_adapter_trino_validation.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/adapters/trino/tests/test_integration_runtime_trino.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/adapters/trino/tests/test_integration_trino_validation.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/continuo_python_runtime/__init__.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/continuo_python_runtime/cli.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/continuo_python_runtime/closure.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/continuo_python_runtime/conform.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/continuo_python_runtime/context.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/continuo_python_runtime/contract/__init__.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/continuo_python_runtime/contract/loader.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/continuo_python_runtime/contract/merge.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/continuo_python_runtime/contract/model.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/continuo_python_runtime/contract/paths.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/continuo_python_runtime/errors.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/continuo_python_runtime/harness.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/continuo_python_runtime/hashing.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/continuo_python_runtime/lint.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/continuo_python_runtime/types.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/continuo_python_runtime/validation/__init__.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/continuo_python_runtime/validation/runner.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/continuo_python_runtime/validation/s3.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/contract/README.md +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/contract/continuo_engine_contract/__init__.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/contract/continuo_engine_contract/config.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/contract/continuo_engine_contract/port.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/contract/continuo_engine_contract/result.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/contract/continuo_engine_contract/sql.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/contract/continuo_engine_contract/types.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/contract/tests/__init__.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/contract/tests/test_config.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/contract/tests/test_contract_types.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/contract/tests/test_port.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/contract/tests/test_result.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/contract/tests/test_sql.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/docs/boundary-contract.md +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/docs/superpowers/plans/2026-07-31-python-runtime.md +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/docs/superpowers/plans/2026-08-07-step-3b-config-three-part-hash.md +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/docs/superpowers/specs/2026-07-31-python-runtime-design.md +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/template/.github/workflows/release.yml +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/template/README.md +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/template/contracts/example.yml +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/template/scripts/example.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/__init__.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/conftest.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/contract/__init__.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/contract/test_loader.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/contract/test_merge.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/contract/test_model.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/smoke/node_smoke/contracts/smoke.yml +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/smoke/node_smoke/scripts/smoke.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/smoke/postgres-stack/docker-compose.yml +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/smoke/trino-stack/catalog/iceberg.properties +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/smoke/trino-stack/docker-compose.yml +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/test_cli.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/test_closure.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/test_conform.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/test_context.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/test_contract_pin_consistency.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/test_errors.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/test_harness.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/test_hashing.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/test_image_smoke_validation.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/test_lint.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/test_package.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/test_template.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/test_types.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/test_validation_runner.py +0 -0
- {continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/tests/test_validation_s3.py +0 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Something in the Continuo Python runtime behaves incorrectly.
|
|
3
|
+
labels: ["bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
Please do not report security vulnerabilities here — see SECURITY.md.
|
|
9
|
+
|
|
10
|
+
- type: textarea
|
|
11
|
+
id: what-happened
|
|
12
|
+
attributes:
|
|
13
|
+
label: What happened
|
|
14
|
+
description: What did you observe, and what did you expect instead?
|
|
15
|
+
validations:
|
|
16
|
+
required: true
|
|
17
|
+
|
|
18
|
+
- type: textarea
|
|
19
|
+
id: reproduce
|
|
20
|
+
attributes:
|
|
21
|
+
label: Steps to reproduce
|
|
22
|
+
placeholder: |
|
|
23
|
+
1. Write a contract with ...
|
|
24
|
+
2. Run `continuo-runtime validate ...`
|
|
25
|
+
3. Observe ...
|
|
26
|
+
validations:
|
|
27
|
+
required: true
|
|
28
|
+
|
|
29
|
+
- type: dropdown
|
|
30
|
+
id: component
|
|
31
|
+
attributes:
|
|
32
|
+
label: Which component
|
|
33
|
+
multiple: true
|
|
34
|
+
options:
|
|
35
|
+
- continuo_python_runtime (harness / CLI)
|
|
36
|
+
- contract (continuo-engine-contract)
|
|
37
|
+
- adapters/postgres
|
|
38
|
+
- adapters/trino
|
|
39
|
+
- template
|
|
40
|
+
- CI (.github/workflows)
|
|
41
|
+
- Not sure
|
|
42
|
+
validations:
|
|
43
|
+
required: true
|
|
44
|
+
|
|
45
|
+
- type: input
|
|
46
|
+
id: version
|
|
47
|
+
attributes:
|
|
48
|
+
label: Version
|
|
49
|
+
description: Package version (PyPI) or commit SHA.
|
|
50
|
+
placeholder: "v0.3.0"
|
|
51
|
+
validations:
|
|
52
|
+
required: true
|
|
53
|
+
|
|
54
|
+
- type: textarea
|
|
55
|
+
id: logs
|
|
56
|
+
attributes:
|
|
57
|
+
label: Relevant logs
|
|
58
|
+
description: Please redact any credentials before pasting.
|
|
59
|
+
render: shell
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Propose a change or addition to the Continuo Python runtime.
|
|
3
|
+
labels: ["enhancement"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: problem
|
|
7
|
+
attributes:
|
|
8
|
+
label: What problem does this solve
|
|
9
|
+
description: Describe the situation you are in, not the solution you have in mind.
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: proposal
|
|
15
|
+
attributes:
|
|
16
|
+
label: What you would like to happen
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
|
|
20
|
+
- type: textarea
|
|
21
|
+
id: alternatives
|
|
22
|
+
attributes:
|
|
23
|
+
label: Alternatives you considered
|
|
24
|
+
|
|
25
|
+
- type: checkboxes
|
|
26
|
+
id: contribute
|
|
27
|
+
attributes:
|
|
28
|
+
label: Contribution
|
|
29
|
+
options:
|
|
30
|
+
- label: I am willing to open a pull request for this.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
## What this changes
|
|
2
|
+
|
|
3
|
+
<!-- One or two sentences. Link the issue this addresses. -->
|
|
4
|
+
|
|
5
|
+
Closes #
|
|
6
|
+
|
|
7
|
+
## Why
|
|
8
|
+
|
|
9
|
+
<!-- What problem does this solve? -->
|
|
10
|
+
|
|
11
|
+
## How it was verified
|
|
12
|
+
|
|
13
|
+
<!-- The commands you ran and what they printed. "Tests pass" on its own is not enough. -->
|
|
14
|
+
|
|
15
|
+
## Checklist
|
|
16
|
+
|
|
17
|
+
- [ ] Every commit is signed off (`git commit -s`) — the `dco` check enforces this
|
|
18
|
+
- [ ] Tests added or updated for the behavior changed
|
|
19
|
+
- [ ] `uv run ruff check .` and `uv run mypy` (relevant packages) pass
|
|
20
|
+
- [ ] `scripts/security-scan.sh` passes (dependency or credential-adjacent changes)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Dependabot keeps dependencies current so that known CVEs are fixed by an
|
|
2
|
+
# upgrade before a scanner has to report them.
|
|
3
|
+
#
|
|
4
|
+
# Every ecosystem groups its patch and minor updates into a single pull request
|
|
5
|
+
# per week to keep the noise down. Major updates stay ungrouped because they
|
|
6
|
+
# carry breaking changes and need to be reviewed one at a time.
|
|
7
|
+
version: 2
|
|
8
|
+
|
|
9
|
+
updates:
|
|
10
|
+
# The uv workspace: this package (root), contract/, and the two adapters. All
|
|
11
|
+
# four share one lockfile, but Dependabot still needs one entry per pyproject.toml
|
|
12
|
+
# directory to see each package's own dependency declarations.
|
|
13
|
+
- package-ecosystem: uv
|
|
14
|
+
directories:
|
|
15
|
+
- /
|
|
16
|
+
- /contract
|
|
17
|
+
- /adapters/postgres
|
|
18
|
+
- /adapters/trino
|
|
19
|
+
schedule:
|
|
20
|
+
interval: weekly
|
|
21
|
+
open-pull-requests-limit: 5
|
|
22
|
+
groups:
|
|
23
|
+
python-minor-patch:
|
|
24
|
+
applies-to: version-updates
|
|
25
|
+
update-types: [minor, patch]
|
|
26
|
+
python-security:
|
|
27
|
+
applies-to: security-updates
|
|
28
|
+
patterns: ["*"]
|
|
29
|
+
commit-message:
|
|
30
|
+
prefix: chore(deps)
|
|
31
|
+
|
|
32
|
+
# Actions are a supply-chain surface in their own right: a compromised or
|
|
33
|
+
# abandoned action runs with access to the workflow token.
|
|
34
|
+
- package-ecosystem: github-actions
|
|
35
|
+
directory: /
|
|
36
|
+
schedule:
|
|
37
|
+
interval: weekly
|
|
38
|
+
open-pull-requests-limit: 5
|
|
39
|
+
groups:
|
|
40
|
+
actions:
|
|
41
|
+
applies-to: version-updates
|
|
42
|
+
update-types: [minor, patch]
|
|
43
|
+
actions-security:
|
|
44
|
+
applies-to: security-updates
|
|
45
|
+
patterns: ["*"]
|
|
46
|
+
commit-message:
|
|
47
|
+
prefix: chore(ci)
|
|
48
|
+
|
|
49
|
+
# Dockerfile.postgres and Dockerfile.trino, the published engine images. Most
|
|
50
|
+
# base-image CVEs are fixed by moving to a newer tag.
|
|
51
|
+
- package-ecosystem: docker
|
|
52
|
+
directory: /
|
|
53
|
+
schedule:
|
|
54
|
+
interval: weekly
|
|
55
|
+
open-pull-requests-limit: 5
|
|
56
|
+
groups:
|
|
57
|
+
docker:
|
|
58
|
+
applies-to: version-updates
|
|
59
|
+
update-types: [minor, patch]
|
|
60
|
+
docker-security:
|
|
61
|
+
applies-to: security-updates
|
|
62
|
+
patterns: ["*"]
|
|
63
|
+
commit-message:
|
|
64
|
+
prefix: chore(deps)
|
|
@@ -7,7 +7,7 @@ jobs:
|
|
|
7
7
|
runs-on: ubuntu-latest
|
|
8
8
|
steps:
|
|
9
9
|
- uses: actions/checkout@v4
|
|
10
|
-
- uses: astral-sh/setup-uv@
|
|
10
|
+
- uses: astral-sh/setup-uv@v7
|
|
11
11
|
- name: Sync
|
|
12
12
|
run: uv sync --all-packages --all-groups
|
|
13
13
|
- name: Lint
|
|
@@ -36,7 +36,7 @@ jobs:
|
|
|
36
36
|
runs-on: ubuntu-latest
|
|
37
37
|
steps:
|
|
38
38
|
- uses: actions/checkout@v4
|
|
39
|
-
- uses: astral-sh/setup-uv@
|
|
39
|
+
- uses: astral-sh/setup-uv@v7
|
|
40
40
|
- run: uv sync --all-packages --all-groups
|
|
41
41
|
- name: Start postgres stack
|
|
42
42
|
run: docker compose -f tests/smoke/postgres-stack/docker-compose.yml up -d --wait
|
|
@@ -50,7 +50,7 @@ jobs:
|
|
|
50
50
|
runs-on: ubuntu-latest
|
|
51
51
|
steps:
|
|
52
52
|
- uses: actions/checkout@v4
|
|
53
|
-
- uses: astral-sh/setup-uv@
|
|
53
|
+
- uses: astral-sh/setup-uv@v7
|
|
54
54
|
- run: uv sync --all-packages --all-groups
|
|
55
55
|
- name: Start trino stack
|
|
56
56
|
run: docker compose -f tests/smoke/trino-stack/docker-compose.yml up -d --wait
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: dco
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
# Job name becomes the check-run name, which is what a branch ruleset requires
|
|
13
|
+
# by string. Keep it "dco" so the required check is unambiguous.
|
|
14
|
+
dco:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
with:
|
|
19
|
+
# The whole PR commit range has to be walkable, not just the merge commit.
|
|
20
|
+
fetch-depth: 0
|
|
21
|
+
|
|
22
|
+
- name: Verify every commit is signed off
|
|
23
|
+
env:
|
|
24
|
+
BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
|
25
|
+
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
|
26
|
+
run: |
|
|
27
|
+
set -euo pipefail
|
|
28
|
+
missing=0
|
|
29
|
+
while read -r sha; do
|
|
30
|
+
[ -z "$sha" ] && continue
|
|
31
|
+
# Merge commits are generated by GitHub and carry no sign-off.
|
|
32
|
+
if [ "$(git rev-list --no-walk --count --merges "$sha")" -eq 1 ]; then
|
|
33
|
+
continue
|
|
34
|
+
fi
|
|
35
|
+
if ! git show -s --format='%B' "$sha" | grep -qiE '^Signed-off-by: .+ <.+@.+>$'; then
|
|
36
|
+
echo "::error::Commit $sha ($(git show -s --format='%an' "$sha")) has no Signed-off-by line."
|
|
37
|
+
missing=1
|
|
38
|
+
fi
|
|
39
|
+
done < <(git rev-list "$BASE_SHA".."$HEAD_SHA")
|
|
40
|
+
|
|
41
|
+
if [ "$missing" -ne 0 ]; then
|
|
42
|
+
echo ""
|
|
43
|
+
echo "Every commit needs a Developer Certificate of Origin sign-off (see DCO)."
|
|
44
|
+
echo "Fix an existing branch with:"
|
|
45
|
+
echo " git rebase --signoff origin/main && git push --force-with-lease"
|
|
46
|
+
echo "Sign off future commits automatically with 'git commit -s'."
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
49
|
+
echo "All commits signed off."
|
{continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/.github/workflows/images.yml
RENAMED
|
@@ -56,7 +56,7 @@ jobs:
|
|
|
56
56
|
path: /tmp
|
|
57
57
|
- name: Load image
|
|
58
58
|
run: docker load -i /tmp/cpr-smoke-postgres.tar
|
|
59
|
-
- uses: astral-sh/setup-uv@
|
|
59
|
+
- uses: astral-sh/setup-uv@v7
|
|
60
60
|
- name: Sync
|
|
61
61
|
run: uv sync --all-packages --all-groups
|
|
62
62
|
- name: Image smoke tests (postgres)
|
|
@@ -111,7 +111,7 @@ jobs:
|
|
|
111
111
|
path: /tmp
|
|
112
112
|
- name: Load image
|
|
113
113
|
run: docker load -i /tmp/cpr-smoke-trino.tar
|
|
114
|
-
- uses: astral-sh/setup-uv@
|
|
114
|
+
- uses: astral-sh/setup-uv@v7
|
|
115
115
|
- name: Sync
|
|
116
116
|
run: uv sync --all-packages --all-groups
|
|
117
117
|
- name: Image smoke tests (trino)
|
|
@@ -178,15 +178,15 @@ jobs:
|
|
|
178
178
|
steps:
|
|
179
179
|
- uses: actions/checkout@v4
|
|
180
180
|
- uses: docker/setup-qemu-action@v3
|
|
181
|
-
- uses: docker/setup-buildx-action@
|
|
181
|
+
- uses: docker/setup-buildx-action@v4
|
|
182
182
|
- name: Log in to ghcr.io
|
|
183
|
-
uses: docker/login-action@
|
|
183
|
+
uses: docker/login-action@v4
|
|
184
184
|
with:
|
|
185
185
|
registry: ghcr.io
|
|
186
186
|
username: ${{ github.actor }}
|
|
187
187
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
188
188
|
- name: Build and push ${{ matrix.engine }} image
|
|
189
|
-
uses: docker/build-push-action@
|
|
189
|
+
uses: docker/build-push-action@v7
|
|
190
190
|
with:
|
|
191
191
|
context: .
|
|
192
192
|
file: Dockerfile.${{ matrix.engine }}
|
{continuo_python_runtime-0.3.0 → continuo_python_runtime-0.3.1}/.github/workflows/publish-pypi.yml
RENAMED
|
@@ -44,7 +44,7 @@ jobs:
|
|
|
44
44
|
contents: read # actions/checkout needs read access to the repo
|
|
45
45
|
steps:
|
|
46
46
|
- uses: actions/checkout@v4
|
|
47
|
-
- uses: astral-sh/setup-uv@
|
|
47
|
+
- uses: astral-sh/setup-uv@v7
|
|
48
48
|
- name: Test before publishing
|
|
49
49
|
# `-m "not image"` deselects the image smoke tests; images.yml runs
|
|
50
50
|
# those against a built engine image.
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
name: release
|
|
2
|
+
|
|
3
|
+
# Creates a GitHub Release once BOTH tag-triggered publish workflows
|
|
4
|
+
# (publish-pypi.yml, images.yml) have finished successfully for this exact
|
|
5
|
+
# tag. A Release exists here beyond what PyPI already shows because a tag
|
|
6
|
+
# also ships two ghcr.io images that PyPI knows nothing about — the Release
|
|
7
|
+
# is the one place that says "this tag = these packages + these images."
|
|
8
|
+
#
|
|
9
|
+
# Triggered by the same tag push as its two siblings, rather than by
|
|
10
|
+
# workflow_run watching them complete: `needs:` cannot cross workflow files,
|
|
11
|
+
# and this avoids depending on workflow_run's head_branch semantics for a
|
|
12
|
+
# tag-triggered source run, which nothing else in this repo relies on.
|
|
13
|
+
# Instead the job below polls the Actions API for the sibling runs at this
|
|
14
|
+
# exact commit until both report a conclusion — that only depends on the
|
|
15
|
+
# same push:tags trigger every other release workflow here already uses.
|
|
16
|
+
on:
|
|
17
|
+
push:
|
|
18
|
+
tags:
|
|
19
|
+
# Digit after v: keeps this to release tags, same reasoning continuo's
|
|
20
|
+
# release.yml uses. publish-pypi.yml and images.yml use the looser `v*`
|
|
21
|
+
# and instead guard internally with startsWith(..., 'v') checks, so
|
|
22
|
+
# this is deliberately the stricter of the three triggers.
|
|
23
|
+
- "v[0-9]*"
|
|
24
|
+
|
|
25
|
+
concurrency:
|
|
26
|
+
group: release-${{ github.ref }}
|
|
27
|
+
cancel-in-progress: false
|
|
28
|
+
|
|
29
|
+
permissions:
|
|
30
|
+
contents: read
|
|
31
|
+
|
|
32
|
+
jobs:
|
|
33
|
+
github-release:
|
|
34
|
+
# -test tags are a TestPyPI dry run (see publish-pypi.yml) and skip
|
|
35
|
+
# images.yml's publish job by design (its own if: guards on this same
|
|
36
|
+
# condition) — no public Release for them.
|
|
37
|
+
if: "!contains(github.ref_name, '-test')"
|
|
38
|
+
runs-on: ubuntu-latest
|
|
39
|
+
# Each wait_for call below can itself run up to 30 minutes (its own
|
|
40
|
+
# internal timeout), called twice, sequentially — so this job's ceiling
|
|
41
|
+
# has to clear 60 minutes on its own polling math alone, before even
|
|
42
|
+
# accounting for how long the siblings actually take to run.
|
|
43
|
+
timeout-minutes: 70
|
|
44
|
+
permissions:
|
|
45
|
+
contents: write # gh release create/edit
|
|
46
|
+
actions: read # poll sibling workflow runs
|
|
47
|
+
env:
|
|
48
|
+
TAG: ${{ github.ref_name }}
|
|
49
|
+
SHA: ${{ github.sha }}
|
|
50
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
51
|
+
steps:
|
|
52
|
+
- name: Wait for publish-pypi.yml and images.yml to finish on this commit
|
|
53
|
+
run: |
|
|
54
|
+
set -euo pipefail
|
|
55
|
+
|
|
56
|
+
wait_for() {
|
|
57
|
+
local workflow_file="$1" elapsed=0 interval=20 timeout=1800
|
|
58
|
+
while :; do
|
|
59
|
+
# event=push, not just head_sha: images.yml also triggers on
|
|
60
|
+
# pull_request, and a coincidentally-identical head_sha between
|
|
61
|
+
# an open PR and this tag would otherwise pick up the wrong run.
|
|
62
|
+
# Query params go in the URL, not via -f: gh api switches a
|
|
63
|
+
# request to POST the moment any -f/-F flag is present, and this
|
|
64
|
+
# listing endpoint only accepts GET — it 404s on POST, which
|
|
65
|
+
# under `set -e` would abort this script on the very first poll,
|
|
66
|
+
# every time. Verified against this repo's real API: -f flags
|
|
67
|
+
# 404 here, the URL query string form returns real run data.
|
|
68
|
+
conclusion="$(gh api "repos/${GITHUB_REPOSITORY}/actions/workflows/${workflow_file}/runs?head_sha=${SHA}&event=push" \
|
|
69
|
+
--jq '.workflow_runs[0].conclusion // "pending"')"
|
|
70
|
+
case "${conclusion}" in
|
|
71
|
+
success)
|
|
72
|
+
echo "${workflow_file}: success"
|
|
73
|
+
return 0
|
|
74
|
+
;;
|
|
75
|
+
pending)
|
|
76
|
+
# Covers both "no matching run yet" (API eventual
|
|
77
|
+
# consistency right after the push) and "run exists but
|
|
78
|
+
# still queued/in_progress" — conclusion is JSON null in
|
|
79
|
+
# both cases until the run completes.
|
|
80
|
+
;;
|
|
81
|
+
*)
|
|
82
|
+
echo "::error::${workflow_file} concluded '${conclusion}' for ${SHA}; not creating a Release."
|
|
83
|
+
exit 1
|
|
84
|
+
;;
|
|
85
|
+
esac
|
|
86
|
+
elapsed=$((elapsed + interval))
|
|
87
|
+
if [ "${elapsed}" -ge "${timeout}" ]; then
|
|
88
|
+
echo "::error::timed out after ${timeout}s waiting for ${workflow_file} to finish on ${SHA}."
|
|
89
|
+
exit 1
|
|
90
|
+
fi
|
|
91
|
+
sleep "${interval}"
|
|
92
|
+
done
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
wait_for "publish-pypi.yml"
|
|
96
|
+
wait_for "images.yml"
|
|
97
|
+
|
|
98
|
+
- name: Extract this version's CHANGELOG section
|
|
99
|
+
id: notes
|
|
100
|
+
run: |
|
|
101
|
+
set -euo pipefail
|
|
102
|
+
VERSION="${TAG#v}"
|
|
103
|
+
# Print the body between "## [X.Y.Z]" and the next "## [" heading.
|
|
104
|
+
if grep -qE "^## \[${VERSION}\]" CHANGELOG.md; then
|
|
105
|
+
awk -v ver="## [${VERSION}]" '
|
|
106
|
+
index($0, ver) == 1 { found = 1; next }
|
|
107
|
+
found && /^## \[/ { exit }
|
|
108
|
+
found { print }
|
|
109
|
+
' CHANGELOG.md > /tmp/release-body.md
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
if [ -s /tmp/release-body.md ]; then
|
|
113
|
+
echo "generate=false" >> "$GITHUB_OUTPUT"
|
|
114
|
+
else
|
|
115
|
+
# A tag with no matching CHANGELOG.md section (e.g. someone
|
|
116
|
+
# forgot to add one before tagging) still gets a Release — just
|
|
117
|
+
# with GitHub's generated notes instead of failing the job over
|
|
118
|
+
# a missing doc update.
|
|
119
|
+
echo "::warning::no '## [${VERSION}]' section in CHANGELOG.md; falling back to generated notes."
|
|
120
|
+
echo "generate=true" >> "$GITHUB_OUTPUT"
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
- name: Create the Release
|
|
124
|
+
run: |
|
|
125
|
+
set -euo pipefail
|
|
126
|
+
# Idempotent: re-running this workflow for an existing tag updates
|
|
127
|
+
# the Release rather than failing.
|
|
128
|
+
if gh release view "${TAG}" --repo "${GITHUB_REPOSITORY}" >/dev/null 2>&1; then
|
|
129
|
+
if [ "${{ steps.notes.outputs.generate }}" = "true" ]; then
|
|
130
|
+
gh release edit "${TAG}" --repo "${GITHUB_REPOSITORY}" --latest
|
|
131
|
+
else
|
|
132
|
+
gh release edit "${TAG}" --repo "${GITHUB_REPOSITORY}" \
|
|
133
|
+
--notes-file /tmp/release-body.md --latest
|
|
134
|
+
fi
|
|
135
|
+
elif [ "${{ steps.notes.outputs.generate }}" = "true" ]; then
|
|
136
|
+
gh release create "${TAG}" --repo "${GITHUB_REPOSITORY}" \
|
|
137
|
+
--title "${TAG}" --generate-notes --latest
|
|
138
|
+
else
|
|
139
|
+
gh release create "${TAG}" --repo "${GITHUB_REPOSITORY}" \
|
|
140
|
+
--title "${TAG}" --notes-file /tmp/release-body.md --latest
|
|
141
|
+
fi
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
name: security
|
|
2
|
+
|
|
3
|
+
# Deliberately separate from ci.yml so a scanner failure or the weekly schedule
|
|
4
|
+
# never blocks or piggybacks on the test/lint pipeline.
|
|
5
|
+
on:
|
|
6
|
+
pull_request:
|
|
7
|
+
branches:
|
|
8
|
+
- main
|
|
9
|
+
push:
|
|
10
|
+
branches:
|
|
11
|
+
- main
|
|
12
|
+
schedule:
|
|
13
|
+
# Weekly, Monday 04:00 UTC. The scheduled run is the point of this workflow:
|
|
14
|
+
# most vulnerabilities are disclosed after the code that depends on them was
|
|
15
|
+
# last touched, so a pull-request-only trigger never sees them.
|
|
16
|
+
- cron: "0 4 * * 1"
|
|
17
|
+
|
|
18
|
+
concurrency:
|
|
19
|
+
# Keyed by event as well as ref. A schedule event and a push to main both carry
|
|
20
|
+
# github.ref == refs/heads/main, so keying on ref alone would put them in one
|
|
21
|
+
# group and let a routine merge, via cancel-in-progress, abort the weekly
|
|
22
|
+
# full-history secret scan — the run this workflow exists for. Including
|
|
23
|
+
# github.event_name isolates the scheduled run while still superseding stale
|
|
24
|
+
# per-PR runs (each PR has a distinct ref).
|
|
25
|
+
group: security-${{ github.ref }}-${{ github.event_name }}
|
|
26
|
+
cancel-in-progress: true
|
|
27
|
+
|
|
28
|
+
# Each job uploads its findings as SARIF, so they land in Security > Code scanning
|
|
29
|
+
# instead of scrolling away in a job log. security-events: write is what permits
|
|
30
|
+
# that upload; contents: read has to be restated because a permissions block
|
|
31
|
+
# replaces the default set rather than adding to it.
|
|
32
|
+
#
|
|
33
|
+
# Note the Security tab will show findings the blocking gate deliberately
|
|
34
|
+
# ignores: the Trivy dependency scan is advisory by design. A green pipeline
|
|
35
|
+
# with open alerts is the intended state, not a contradiction.
|
|
36
|
+
permissions:
|
|
37
|
+
contents: read
|
|
38
|
+
security-events: write
|
|
39
|
+
|
|
40
|
+
jobs:
|
|
41
|
+
secrets:
|
|
42
|
+
name: Secret scan (blocking)
|
|
43
|
+
runs-on: ubuntu-latest
|
|
44
|
+
timeout-minutes: 15
|
|
45
|
+
steps:
|
|
46
|
+
# Always full history: pull_request and push both need to walk a commit
|
|
47
|
+
# range (below), and this repository is small enough (a few hundred KB,
|
|
48
|
+
# well under a second to scan) that fetch-depth: 0 costs nothing on every
|
|
49
|
+
# trigger rather than only on the schedule.
|
|
50
|
+
- uses: actions/checkout@v4
|
|
51
|
+
with:
|
|
52
|
+
fetch-depth: 0
|
|
53
|
+
|
|
54
|
+
# pull_request scans exactly the commits the PR introduces (base..head).
|
|
55
|
+
# A `dir` scan of the final working tree would miss a secret added in one
|
|
56
|
+
# commit and removed in a later one within the same PR — the working tree
|
|
57
|
+
# never carries it, but a history-preserving merge still makes that commit
|
|
58
|
+
# reachable from main. push scans the commits a direct push to main added
|
|
59
|
+
# (before..after), for the same reason. The weekly schedule walks every
|
|
60
|
+
# commit reachable from HEAD, catching anything that entered the
|
|
61
|
+
# repository before this gate existed.
|
|
62
|
+
- name: Run gitleaks
|
|
63
|
+
env:
|
|
64
|
+
SARIF_DIR: sarif
|
|
65
|
+
run: |
|
|
66
|
+
case "${{ github.event_name }}" in
|
|
67
|
+
schedule)
|
|
68
|
+
bash scripts/security-scan.sh secrets --history
|
|
69
|
+
;;
|
|
70
|
+
pull_request)
|
|
71
|
+
bash scripts/security-scan.sh secrets --range \
|
|
72
|
+
"${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}"
|
|
73
|
+
;;
|
|
74
|
+
push)
|
|
75
|
+
before="${{ github.event.before }}"
|
|
76
|
+
# A zero SHA means there is no prior commit to diff from — a new
|
|
77
|
+
# branch's first push, or history rewritten out from under this
|
|
78
|
+
# ref. Neither has a meaningful range, so fall back to scanning
|
|
79
|
+
# just the commit that was pushed.
|
|
80
|
+
if [ "${before}" = "0000000000000000000000000000000000000000" ]; then
|
|
81
|
+
before="${{ github.event.after }}^"
|
|
82
|
+
fi
|
|
83
|
+
bash scripts/security-scan.sh secrets --range "${before}..${{ github.event.after }}"
|
|
84
|
+
;;
|
|
85
|
+
esac
|
|
86
|
+
# if: always() — a blocking scan that fails must still publish what it
|
|
87
|
+
# found, otherwise the findings that justify the failure never appear.
|
|
88
|
+
#
|
|
89
|
+
# continue-on-error: true — code scanning needs GitHub Advanced Security,
|
|
90
|
+
# free on a public repo but not on a private one. This repo is private
|
|
91
|
+
# until the open-sourcing work lands, so the upload 403s
|
|
92
|
+
# ("Resource not accessible by integration") on every run until then.
|
|
93
|
+
# The upload is reporting, not the gate; gitleaks failing the step above
|
|
94
|
+
# is what actually blocks a merge, and must keep doing so independent of
|
|
95
|
+
# whether the upload succeeds.
|
|
96
|
+
- name: Upload SARIF to code scanning
|
|
97
|
+
if: always()
|
|
98
|
+
continue-on-error: true
|
|
99
|
+
uses: github/codeql-action/upload-sarif@v3
|
|
100
|
+
with:
|
|
101
|
+
sarif_file: sarif/
|
|
102
|
+
category: gitleaks
|
|
103
|
+
|
|
104
|
+
dependencies:
|
|
105
|
+
name: Dependency CVEs (advisory)
|
|
106
|
+
runs-on: ubuntu-latest
|
|
107
|
+
timeout-minutes: 20
|
|
108
|
+
steps:
|
|
109
|
+
- uses: actions/checkout@v4
|
|
110
|
+
|
|
111
|
+
# Advisory: reports HIGH/CRITICAL and always exits 0. Base-image and
|
|
112
|
+
# transitive CVEs are often unfixable upstream, so gating on them would
|
|
113
|
+
# block every merge behind an ignore-list edit. Dependabot is what actually
|
|
114
|
+
# resolves these; this job exists to make them visible.
|
|
115
|
+
- name: Run Trivy dependency scan
|
|
116
|
+
env:
|
|
117
|
+
SARIF_DIR: sarif
|
|
118
|
+
run: bash scripts/security-scan.sh deps
|
|
119
|
+
# if: always() — a blocking scan that fails must still publish what it
|
|
120
|
+
# found, otherwise the findings that justify the failure never appear.
|
|
121
|
+
#
|
|
122
|
+
# continue-on-error: true — see the identical note on the secrets job;
|
|
123
|
+
# same GHAS-requires-public-repo cause, same fix.
|
|
124
|
+
- name: Upload SARIF to code scanning
|
|
125
|
+
if: always()
|
|
126
|
+
continue-on-error: true
|
|
127
|
+
uses: github/codeql-action/upload-sarif@v3
|
|
128
|
+
with:
|
|
129
|
+
sarif_file: sarif/
|
|
130
|
+
category: trivy-fs
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# gitleaks configuration.
|
|
2
|
+
#
|
|
3
|
+
# Extends the upstream default ruleset rather than replacing it, so rules added
|
|
4
|
+
# upstream apply automatically. Only repository-specific exemptions live here.
|
|
5
|
+
|
|
6
|
+
[extend]
|
|
7
|
+
useDefault = true
|
|
8
|
+
|
|
9
|
+
[allowlist]
|
|
10
|
+
description = "Paths that contain no live credentials"
|
|
11
|
+
|
|
12
|
+
paths = [
|
|
13
|
+
# Unanchored throughout: the working-tree scan (scripts/security-scan.sh)
|
|
14
|
+
# mounts the repo at /repo and passes that as the scan target, so gitleaks
|
|
15
|
+
# matches these patterns against absolute paths like
|
|
16
|
+
# /repo/.worktrees/stale/file — a leading `^` would never match the actual
|
|
17
|
+
# prefix and silently disable the exclusion. Verified against v8.24.3 by
|
|
18
|
+
# planting a fake AWS key under .worktrees/ and confirming a start-anchored
|
|
19
|
+
# pattern let it through while an unanchored one catches it.
|
|
20
|
+
#
|
|
21
|
+
# Local agent worktrees hold full stale copies of every tracked file, so a
|
|
22
|
+
# finding in the real tree would otherwise be reported once per worktree.
|
|
23
|
+
'''(^|/)\.worktrees/''',
|
|
24
|
+
'''(^|/)\.claude/''',
|
|
25
|
+
# Build/tooling caches, never committed.
|
|
26
|
+
'''(^|/)\.venv/''',
|
|
27
|
+
'''(^|/)\.mypy_cache/''',
|
|
28
|
+
'''(^|/)\.ruff_cache/''',
|
|
29
|
+
'''(^|/)\.pytest_cache/''',
|
|
30
|
+
'''(^|/)dist/''',
|
|
31
|
+
# The tier-2 smoke stacks under tests/smoke/ use documented, throwaway
|
|
32
|
+
# default credentials for local-only containers (e.g. MinIO's published
|
|
33
|
+
# "minioadmin"/"minioadmin", Postgres's "continuo"/"continuo") — not
|
|
34
|
+
# secrets, and never reachable outside the compose network they define.
|
|
35
|
+
'''(^|/)tests/smoke/[^/]+/docker-compose\.yml$''',
|
|
36
|
+
]
|