aetherx-reprocert 0.2.2a1__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.
Files changed (73) hide show
  1. aetherx_reprocert-0.2.2a1/.github/ISSUE_TEMPLATE/adoption.yml +78 -0
  2. aetherx_reprocert-0.2.2a1/.github/ISSUE_TEMPLATE/bug.yml +71 -0
  3. aetherx_reprocert-0.2.2a1/.github/ISSUE_TEMPLATE/config.yml +8 -0
  4. aetherx_reprocert-0.2.2a1/.github/ISSUE_TEMPLATE/feature.yml +45 -0
  5. aetherx_reprocert-0.2.2a1/.github/PULL_REQUEST_TEMPLATE.md +20 -0
  6. aetherx_reprocert-0.2.2a1/.github/dependabot.yml +13 -0
  7. aetherx_reprocert-0.2.2a1/.github/workflows/attested-demo.yml +70 -0
  8. aetherx_reprocert-0.2.2a1/.github/workflows/ci.yml +217 -0
  9. aetherx_reprocert-0.2.2a1/.github/workflows/release.yml +73 -0
  10. aetherx_reprocert-0.2.2a1/.github/workflows/stable-channel-proof.yml +64 -0
  11. aetherx_reprocert-0.2.2a1/.gitignore +16 -0
  12. aetherx_reprocert-0.2.2a1/CHANGELOG.md +58 -0
  13. aetherx_reprocert-0.2.2a1/CODE_OF_CONDUCT.md +16 -0
  14. aetherx_reprocert-0.2.2a1/CONTRIBUTING.md +41 -0
  15. aetherx_reprocert-0.2.2a1/GOVERNANCE.md +39 -0
  16. aetherx_reprocert-0.2.2a1/LICENSE +201 -0
  17. aetherx_reprocert-0.2.2a1/NOTICE +7 -0
  18. aetherx_reprocert-0.2.2a1/PKG-INFO +373 -0
  19. aetherx_reprocert-0.2.2a1/README.md +344 -0
  20. aetherx_reprocert-0.2.2a1/ROADMAP.md +88 -0
  21. aetherx_reprocert-0.2.2a1/SECURITY.md +26 -0
  22. aetherx_reprocert-0.2.2a1/SUPPORT.md +35 -0
  23. aetherx_reprocert-0.2.2a1/action.yml +85 -0
  24. aetherx_reprocert-0.2.2a1/docs/ADOPTION.md +102 -0
  25. aetherx_reprocert-0.2.2a1/docs/ARCHITECTURE.md +44 -0
  26. aetherx_reprocert-0.2.2a1/docs/ATTESTATION.md +38 -0
  27. aetherx_reprocert-0.2.2a1/docs/CLAIM_FORMAT.md +55 -0
  28. aetherx_reprocert-0.2.2a1/docs/CONTAINER_PROFILE.md +59 -0
  29. aetherx_reprocert-0.2.2a1/docs/INTEGRATION_GUIDE.md +81 -0
  30. aetherx_reprocert-0.2.2a1/docs/JUNIT.md +30 -0
  31. aetherx_reprocert-0.2.2a1/docs/POLICY.md +59 -0
  32. aetherx_reprocert-0.2.2a1/docs/PUBLISHING.md +52 -0
  33. aetherx_reprocert-0.2.2a1/docs/PYTEST.md +38 -0
  34. aetherx_reprocert-0.2.2a1/docs/QUICKSTART_5_MIN.md +79 -0
  35. aetherx_reprocert-0.2.2a1/docs/SUITES.md +51 -0
  36. aetherx_reprocert-0.2.2a1/docs/THREAT_MODEL.md +51 -0
  37. aetherx_reprocert-0.2.2a1/docs/TROUBLESHOOTING.md +51 -0
  38. aetherx_reprocert-0.2.2a1/examples/basic/claim.yml +30 -0
  39. aetherx_reprocert-0.2.2a1/examples/basic/produce.py +7 -0
  40. aetherx_reprocert-0.2.2a1/examples/junit/claim.yml +32 -0
  41. aetherx_reprocert-0.2.2a1/examples/junit/make_report.py +13 -0
  42. aetherx_reprocert-0.2.2a1/examples/policy/container-required.yml +12 -0
  43. aetherx_reprocert-0.2.2a1/examples/policy/strict-ci.yml +14 -0
  44. aetherx_reprocert-0.2.2a1/examples/pytest-native/test_sample.py +6 -0
  45. aetherx_reprocert-0.2.2a1/examples/suite.yml +9 -0
  46. aetherx_reprocert-0.2.2a1/pyproject.toml +47 -0
  47. aetherx_reprocert-0.2.2a1/schemas/attestation-predicate-v1.schema.json +55 -0
  48. aetherx_reprocert-0.2.2a1/schemas/certificate-v1alpha1.schema.json +14 -0
  49. aetherx_reprocert-0.2.2a1/schemas/claim-v1alpha1.schema.json +131 -0
  50. aetherx_reprocert-0.2.2a1/schemas/policy-v1alpha1.schema.json +44 -0
  51. aetherx_reprocert-0.2.2a1/schemas/suite-v1alpha1.schema.json +33 -0
  52. aetherx_reprocert-0.2.2a1/src/reprocert/__init__.py +3 -0
  53. aetherx_reprocert-0.2.2a1/src/reprocert/__main__.py +3 -0
  54. aetherx_reprocert-0.2.2a1/src/reprocert/attestation.py +60 -0
  55. aetherx_reprocert-0.2.2a1/src/reprocert/certificate.py +29 -0
  56. aetherx_reprocert-0.2.2a1/src/reprocert/claim.py +207 -0
  57. aetherx_reprocert-0.2.2a1/src/reprocert/cli.py +488 -0
  58. aetherx_reprocert-0.2.2a1/src/reprocert/container.py +138 -0
  59. aetherx_reprocert-0.2.2a1/src/reprocert/doctor.py +175 -0
  60. aetherx_reprocert-0.2.2a1/src/reprocert/environment.py +67 -0
  61. aetherx_reprocert-0.2.2a1/src/reprocert/init_project.py +210 -0
  62. aetherx_reprocert-0.2.2a1/src/reprocert/junit.py +154 -0
  63. aetherx_reprocert-0.2.2a1/src/reprocert/policy.py +266 -0
  64. aetherx_reprocert-0.2.2a1/src/reprocert/pytest_adapter.py +84 -0
  65. aetherx_reprocert-0.2.2a1/src/reprocert/runner.py +302 -0
  66. aetherx_reprocert-0.2.2a1/src/reprocert/suite.py +151 -0
  67. aetherx_reprocert-0.2.2a1/src/reprocert/util.py +46 -0
  68. aetherx_reprocert-0.2.2a1/src/reprocert/verification.py +158 -0
  69. aetherx_reprocert-0.2.2a1/tests/test_adoption.py +187 -0
  70. aetherx_reprocert-0.2.2a1/tests/test_release_workflow.py +7 -0
  71. aetherx_reprocert-0.2.2a1/tests/test_reprocert.py +77 -0
  72. aetherx_reprocert-0.2.2a1/tests/test_self_service.py +84 -0
  73. aetherx_reprocert-0.2.2a1/tests/test_v02.py +218 -0
@@ -0,0 +1,78 @@
1
+ name: Adoption / Integration Help
2
+ description: Get help adding ReproCert to a real repository or CI workflow.
3
+ title: "[Adoption] "
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ ReproCert can be added as a small evidence layer on top of an existing test, benchmark, build, or research workflow. Keep this issue non-sensitive: do not include credentials, private source code, customer data, or confidential artifacts.
9
+
10
+ - type: input
11
+ id: repository
12
+ attributes:
13
+ label: Repository URL
14
+ description: Public repository URL if available. For private projects, describe the stack without sharing confidential details.
15
+ placeholder: https://github.com/owner/repository
16
+ validations:
17
+ required: true
18
+
19
+ - type: textarea
20
+ id: claim
21
+ attributes:
22
+ label: What claim do you want to verify?
23
+ description: State one concrete technical claim.
24
+ placeholder: "Example: the benchmark median stays below 250 ms, or all pytest checks complete with zero failures."
25
+ validations:
26
+ required: true
27
+
28
+ - type: textarea
29
+ id: current_workflow
30
+ attributes:
31
+ label: Current command or CI workflow
32
+ description: Show the existing command or a small non-sensitive workflow excerpt.
33
+ render: shell
34
+ validations:
35
+ required: true
36
+
37
+ - type: textarea
38
+ id: evidence
39
+ attributes:
40
+ label: Evidence already produced
41
+ description: Examples include JUnit XML, benchmark JSON, build artifacts, hashes, or logs.
42
+ placeholder: junit.xml, benchmark.json, dist/package.whl
43
+ validations:
44
+ required: false
45
+
46
+ - type: dropdown
47
+ id: integration
48
+ attributes:
49
+ label: Preferred integration
50
+ options:
51
+ - GitHub Action
52
+ - ReproCert CLI
53
+ - Pytest-native adapter
54
+ - JUnit integration
55
+ - Multi-claim suite
56
+ - Policy gate
57
+ - Signed attestation
58
+ - Not sure — recommend the smallest useful integration
59
+ validations:
60
+ required: true
61
+
62
+ - type: textarea
63
+ id: constraints
64
+ attributes:
65
+ label: Constraints
66
+ description: Note OS, Python version, CI provider, security restrictions, or "no product-code changes" requirements.
67
+ validations:
68
+ required: false
69
+
70
+ - type: checkboxes
71
+ id: boundaries
72
+ attributes:
73
+ label: Public issue boundaries
74
+ options:
75
+ - label: I confirm this issue contains no credentials, private customer data, confidential source code, or sensitive exploit details.
76
+ required: true
77
+ - label: I understand a ReproCert PASS result does not by itself establish security certification, scientific truth, or benchmark fairness.
78
+ required: true
@@ -0,0 +1,71 @@
1
+ name: Bug report
2
+ description: Report a reproducible defect in ReproCert.
3
+ title: "[Bug] "
4
+ labels: []
5
+ body:
6
+ - type: markdown
7
+ attributes:
8
+ value: |
9
+ Thanks for helping improve ReproCert. Do not include credentials, private source code, customer data, or sensitive vulnerability details.
10
+
11
+ - type: input
12
+ id: version
13
+ attributes:
14
+ label: ReproCert version or commit
15
+ placeholder: 0.1.0a1 or commit SHA
16
+ validations:
17
+ required: true
18
+
19
+ - type: dropdown
20
+ id: surface
21
+ attributes:
22
+ label: Affected surface
23
+ options:
24
+ - CLI
25
+ - GitHub Action
26
+ - Claim schema
27
+ - Certificate verification
28
+ - Evidence collection
29
+ - Packaging / installation
30
+ - Documentation
31
+ - Other
32
+ validations:
33
+ required: true
34
+
35
+ - type: textarea
36
+ id: reproduction
37
+ attributes:
38
+ label: Minimal reproduction
39
+ description: Provide the smallest non-sensitive example that reproduces the issue.
40
+ validations:
41
+ required: true
42
+
43
+ - type: textarea
44
+ id: expected
45
+ attributes:
46
+ label: Expected behavior
47
+ validations:
48
+ required: true
49
+
50
+ - type: textarea
51
+ id: observed
52
+ attributes:
53
+ label: Observed behavior
54
+ validations:
55
+ required: true
56
+
57
+ - type: input
58
+ id: platform
59
+ attributes:
60
+ label: Platform and Python version
61
+ placeholder: Ubuntu 24.04 / Python 3.13
62
+ validations:
63
+ required: true
64
+
65
+ - type: checkboxes
66
+ id: safety
67
+ attributes:
68
+ label: Public issue safety
69
+ options:
70
+ - label: I confirm this report contains no credentials, confidential data, private source code, or sensitive exploit details.
71
+ required: true
@@ -0,0 +1,8 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: Security guidance
4
+ url: https://github.com/AETHERXGLOBAL/reprocert/blob/main/SECURITY.md
5
+ about: Do not publish sensitive vulnerability details in a public issue.
6
+ - name: Support guidance
7
+ url: https://github.com/AETHERXGLOBAL/reprocert/blob/main/SUPPORT.md
8
+ about: Read the support boundary before opening a public issue.
@@ -0,0 +1,45 @@
1
+ name: Feature proposal
2
+ description: Propose a developer-facing capability for ReproCert.
3
+ title: "[Feature] "
4
+ labels: []
5
+ body:
6
+ - type: markdown
7
+ attributes:
8
+ value: |
9
+ Strong proposals start from a concrete developer problem and explain the evidence/trust semantics before implementation detail.
10
+
11
+ - type: textarea
12
+ id: problem
13
+ attributes:
14
+ label: Developer problem
15
+ description: What workflow is difficult, ambiguous, or unreliable today?
16
+ validations:
17
+ required: true
18
+
19
+ - type: textarea
20
+ id: proposal
21
+ attributes:
22
+ label: Proposed capability
23
+ description: Describe the smallest useful capability.
24
+ validations:
25
+ required: true
26
+
27
+ - type: textarea
28
+ id: semantics
29
+ attributes:
30
+ label: Evidence and verdict semantics
31
+ description: How should PASS, FAIL, INCONCLUSIVE, or ERROR behave if relevant?
32
+
33
+ - type: textarea
34
+ id: trust
35
+ attributes:
36
+ label: Trust-boundary impact
37
+ description: Does this affect signing, producer identity, evidence trust, remote execution, secrets, or code execution?
38
+ validations:
39
+ required: true
40
+
41
+ - type: textarea
42
+ id: alternatives
43
+ attributes:
44
+ label: Existing tools or alternatives
45
+ description: Which adjacent tools or standards already solve part of the problem?
@@ -0,0 +1,20 @@
1
+ ## What changes?
2
+
3
+ Describe the smallest coherent change and the developer problem it addresses.
4
+
5
+ ## Evidence
6
+
7
+ - [ ] Tests added or updated where behavior changed.
8
+ - [ ] `pytest` passes locally or CI evidence is expected to establish it.
9
+ - [ ] Documentation updated where public behavior changed.
10
+ - [ ] Claim/verdict semantics remain explicit.
11
+
12
+ ## Trust-boundary review
13
+
14
+ - [ ] This change does not silently expand command execution, secret access, evidence trust, signing authority, or producer-authentication claims.
15
+ - [ ] Any new trust assumption is documented.
16
+ - [ ] No credentials, private customer data, or confidential implementation material is included.
17
+
18
+ ## Claim discipline
19
+
20
+ - [ ] No novelty, superiority, security-certification, scientific-validity, or production-readiness claim is introduced without evidence.
@@ -0,0 +1,13 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: pip
4
+ directory: /
5
+ schedule:
6
+ interval: monthly
7
+ open-pull-requests-limit: 5
8
+
9
+ - package-ecosystem: github-actions
10
+ directory: /
11
+ schedule:
12
+ interval: monthly
13
+ open-pull-requests-limit: 5
@@ -0,0 +1,70 @@
1
+ name: Attested Demo
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ paths:
7
+ - 'src/**'
8
+ - 'examples/**'
9
+ - 'schemas/**'
10
+ - 'pyproject.toml'
11
+ - 'action.yml'
12
+ - '.github/workflows/attested-demo.yml'
13
+ workflow_dispatch:
14
+
15
+ permissions:
16
+ contents: read
17
+ id-token: write
18
+ attestations: write
19
+ artifact-metadata: write
20
+
21
+ jobs:
22
+ certificate:
23
+ name: Produce and attest reference certificate
24
+ runs-on: ubuntu-latest
25
+
26
+ steps:
27
+ - name: Checkout
28
+ uses: actions/checkout@v7
29
+
30
+ - name: Set up Python
31
+ uses: actions/setup-python@v7
32
+ with:
33
+ python-version: '3.13'
34
+
35
+ - name: Install ReproCert
36
+ run: python -m pip install .
37
+
38
+ - name: Produce reference certificate
39
+ working-directory: examples/basic
40
+ run: reprocert run claim.yml --output reprocert-certificate.json
41
+
42
+ - name: Verify certificate and evidence locally
43
+ working-directory: examples/basic
44
+ run: reprocert verify reprocert-certificate.json --claim claim.yml --evidence-root .
45
+
46
+ - name: Build ReproCert custom predicate
47
+ working-directory: examples/basic
48
+ run: |
49
+ reprocert predicate reprocert-certificate.json --output reprocert-predicate.json --json
50
+
51
+ - name: Attest general producer provenance
52
+ uses: actions/attest@v4
53
+ with:
54
+ subject-path: examples/basic/reprocert-certificate.json
55
+
56
+ - name: Attest ReproCert predicate
57
+ uses: actions/attest@v4
58
+ with:
59
+ subject-path: examples/basic/reprocert-certificate.json
60
+ predicate-type: https://raw.githubusercontent.com/AETHERXGLOBAL/reprocert/main/schemas/attestation-predicate-v1.schema.json
61
+ predicate-path: examples/basic/reprocert-predicate.json
62
+
63
+ - name: Upload certificate and predicate
64
+ uses: actions/upload-artifact@v7
65
+ with:
66
+ name: reprocert-reference-evidence
67
+ path: |
68
+ examples/basic/reprocert-certificate.json
69
+ examples/basic/reprocert-predicate.json
70
+ if-no-files-found: error
@@ -0,0 +1,217 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ workflow_dispatch:
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ test:
14
+ name: ${{ matrix.os }} / Python ${{ matrix.python }}
15
+ runs-on: ${{ matrix.os }}
16
+ strategy:
17
+ fail-fast: false
18
+ matrix:
19
+ os: [ubuntu-latest, windows-latest, macos-latest]
20
+ python: ['3.11', '3.13', '3.14']
21
+
22
+ steps:
23
+ - name: Checkout
24
+ uses: actions/checkout@v7
25
+
26
+ - name: Set up Python
27
+ uses: actions/setup-python@v7
28
+ with:
29
+ python-version: ${{ matrix.python }}
30
+
31
+ - name: Install
32
+ run: python -m pip install -e ".[dev]"
33
+
34
+ - name: Unit and adversarial tests
35
+ run: pytest
36
+
37
+ - name: Reference claim round-trip
38
+ working-directory: examples/basic
39
+ shell: bash
40
+ run: |
41
+ reprocert run claim.yml --output certificate.json
42
+ reprocert verify certificate.json --claim claim.yml --evidence-root .
43
+ reprocert inspect certificate.json --json
44
+
45
+ - name: Policy gate round-trip
46
+ working-directory: examples/basic
47
+ shell: bash
48
+ run: |
49
+ reprocert policy certificate.json ../policy/strict-ci.yml --output policy-result.json --json
50
+
51
+ - name: JUnit adapter round-trip
52
+ working-directory: examples/junit
53
+ shell: bash
54
+ run: |
55
+ reprocert run claim.yml --output certificate.json
56
+ reprocert verify certificate.json --claim claim.yml --evidence-root .
57
+
58
+ - name: Pytest-native adapter round-trip
59
+ shell: bash
60
+ run: |
61
+ reprocert pytest --workdir examples/pytest-native --output pytest-native-certificate.json -- -q test_sample.py
62
+ reprocert verify pytest-native-certificate.json --claim examples/pytest-native/.reprocert-pytest-claim.json --evidence-root examples/pytest-native
63
+
64
+ - name: Multi-claim suite round-trip
65
+ working-directory: examples
66
+ shell: bash
67
+ run: |
68
+ reprocert suite suite.yml --output suite-report.json --certificate-dir .reprocert/certificates --json
69
+
70
+ action-smoke:
71
+ name: Reusable Action smoke test
72
+ runs-on: ubuntu-latest
73
+ steps:
74
+ - name: Checkout
75
+ uses: actions/checkout@v7
76
+
77
+ - name: Execute ReproCert Action
78
+ id: reprocert
79
+ uses: ./
80
+ with:
81
+ claim: examples/basic/claim.yml
82
+ certificate: reprocert-action-certificate.json
83
+
84
+ - name: Assert exported verdict and digest
85
+ shell: bash
86
+ run: |
87
+ test "${{ steps.reprocert.outputs.verdict }}" = "PASS"
88
+ test -n "${{ steps.reprocert.outputs.certificate-digest }}"
89
+
90
+ container-profile:
91
+ name: Hardened container profile / Ubuntu
92
+ runs-on: ubuntu-latest
93
+ steps:
94
+ - name: Checkout
95
+ uses: actions/checkout@v7
96
+
97
+ - name: Set up Python
98
+ uses: actions/setup-python@v7
99
+ with:
100
+ python-version: '3.13'
101
+
102
+ - name: Install
103
+ run: python -m pip install -e ".[dev]"
104
+
105
+ - name: Resolve immutable Alpine image identity
106
+ shell: bash
107
+ run: |
108
+ docker pull alpine:3.20
109
+ image="$(docker image inspect alpine:3.20 --format '{{index .RepoDigests 0}}')"
110
+ echo "REPROCERT_TEST_IMAGE=$image" >> "$GITHUB_ENV"
111
+
112
+ - name: Create digest-pinned container claim
113
+ shell: bash
114
+ run: |
115
+ python - <<'PY'
116
+ import json
117
+ import os
118
+ from pathlib import Path
119
+
120
+ claim = {
121
+ "apiVersion": "reprocert.dev/v1alpha1",
122
+ "kind": "ReproducibilityClaim",
123
+ "metadata": {
124
+ "id": "container-profile-smoke",
125
+ "title": "Hardened container execution profile",
126
+ },
127
+ "spec": {
128
+ "command": ["sh", "-c", "printf ok > result.txt"],
129
+ "container": {
130
+ "engine": "docker",
131
+ "image": os.environ["REPROCERT_TEST_IMAGE"],
132
+ "network": "none",
133
+ "read_only_root": True,
134
+ "drop_capabilities": True,
135
+ "no_new_privileges": True,
136
+ "pids_limit": 128,
137
+ },
138
+ "evidence": ["result.txt"],
139
+ "checks": [
140
+ {
141
+ "id": "container-result",
142
+ "source": {"type": "text", "path": "result.txt"},
143
+ "op": "eq",
144
+ "expected": "ok",
145
+ }
146
+ ],
147
+ },
148
+ }
149
+ Path("container-claim.json").write_text(
150
+ json.dumps(claim, indent=2) + "\n",
151
+ encoding="utf-8",
152
+ )
153
+ PY
154
+
155
+ - name: Execute digest-pinned container claim
156
+ shell: bash
157
+ run: |
158
+ set +e
159
+ reprocert run container-claim.json --output container-certificate.json
160
+ rc=$?
161
+ python - <<'PY'
162
+ import json
163
+ from pathlib import Path
164
+ cert = json.loads(Path("container-certificate.json").read_text())
165
+ print(json.dumps({
166
+ "verdict": cert["verdict"],
167
+ "exit_code": cert["run"]["exit_code"],
168
+ "execution_error": cert["run"]["execution_error"],
169
+ "stderr_excerpt": cert["run"]["stderr_excerpt"],
170
+ "container": cert["run"].get("container"),
171
+ }, indent=2))
172
+ PY
173
+ if [ "$rc" -ne 0 ]; then
174
+ exit "$rc"
175
+ fi
176
+ reprocert policy container-certificate.json examples/policy/container-required.yml --output container-policy-result.json
177
+ reprocert inspect container-certificate.json --json
178
+
179
+ - name: Assert hardened profile evidence
180
+ shell: python
181
+ run: |
182
+ import json
183
+ import os
184
+ from pathlib import Path
185
+
186
+ cert = json.loads(Path("container-certificate.json").read_text())
187
+ profile = cert["run"]["container"]
188
+ assert profile["image"] == os.environ["REPROCERT_TEST_IMAGE"]
189
+ assert profile["network"] == "none"
190
+ assert profile["read_only_root"] is True
191
+ assert profile["drop_capabilities"] is True
192
+ assert profile["no_new_privileges"] is True
193
+ assert cert["verdict"] == "PASS"
194
+
195
+ package:
196
+ name: Build package
197
+ runs-on: ubuntu-latest
198
+ steps:
199
+ - name: Checkout
200
+ uses: actions/checkout@v7
201
+
202
+ - name: Set up Python
203
+ uses: actions/setup-python@v7
204
+ with:
205
+ python-version: '3.13'
206
+
207
+ - name: Build isolated package
208
+ run: |
209
+ python -m pip install build
210
+ python -m build
211
+
212
+ - name: Upload package artifact
213
+ uses: actions/upload-artifact@v7
214
+ with:
215
+ name: reprocert-dist
216
+ path: dist/*
217
+ if-no-files-found: error
@@ -0,0 +1,73 @@
1
+ name: Release
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ build:
12
+ name: Build release distributions
13
+ runs-on: ubuntu-latest
14
+
15
+ steps:
16
+ - name: Checkout released source
17
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
18
+
19
+ - name: Set up Python
20
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97
21
+ with:
22
+ python-version: '3.13'
23
+
24
+ - name: Verify release tag matches package version
25
+ shell: python
26
+ env:
27
+ RELEASE_TAG: ${{ github.event.release.tag_name }}
28
+ run: |
29
+ import os
30
+ import tomllib
31
+ from pathlib import Path
32
+
33
+ data = tomllib.loads(Path("pyproject.toml").read_text(encoding="utf-8"))
34
+ version = data["project"]["version"]
35
+ expected = f"v{version}"
36
+ actual = os.environ["RELEASE_TAG"]
37
+ if actual != expected:
38
+ raise SystemExit(
39
+ f"Release tag {actual!r} does not match package version {expected!r}"
40
+ )
41
+ print(f"release identity verified: {actual}")
42
+
43
+ - name: Build distributions
44
+ run: |
45
+ python -m pip install build
46
+ python -m build
47
+
48
+ - name: Upload release distributions
49
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
50
+ with:
51
+ name: python-package-distributions
52
+ path: dist/*
53
+ if-no-files-found: error
54
+
55
+ publish-pypi:
56
+ name: Publish to PyPI
57
+ needs: build
58
+ runs-on: ubuntu-latest
59
+ environment:
60
+ name: pypi
61
+ url: https://pypi.org/project/aetherx-reprocert/
62
+ permissions:
63
+ id-token: write
64
+
65
+ steps:
66
+ - name: Download release distributions
67
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
68
+ with:
69
+ name: python-package-distributions
70
+ path: dist
71
+
72
+ - name: Publish package
73
+ uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33
@@ -0,0 +1,64 @@
1
+ name: Stable v0.2 Channel Proof
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ paths:
7
+ - 'action.yml'
8
+ - 'src/**'
9
+ - 'pyproject.toml'
10
+ - '.github/workflows/stable-channel-proof.yml'
11
+ pull_request:
12
+ paths:
13
+ - '.github/workflows/stable-channel-proof.yml'
14
+ workflow_dispatch:
15
+
16
+ permissions:
17
+ contents: read
18
+
19
+ jobs:
20
+ action-channel:
21
+ name: Consume AETHERXGLOBAL/reprocert@v0.2
22
+ runs-on: ubuntu-latest
23
+ steps:
24
+ - name: Checkout consumer fixture
25
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
26
+
27
+ - name: Consume stable ReproCert action channel
28
+ id: reprocert
29
+ uses: AETHERXGLOBAL/reprocert@v0.2
30
+ with:
31
+ claim: examples/basic/claim.yml
32
+ certificate: stable-channel-certificate.json
33
+
34
+ - name: Assert stable action result
35
+ shell: bash
36
+ run: |
37
+ test "${{ steps.reprocert.outputs.verdict }}" = "PASS"
38
+ test -n "${{ steps.reprocert.outputs.certificate-digest }}"
39
+ test -f stable-channel-certificate.json
40
+
41
+ git-install-channel:
42
+ name: Self-service install from public v0.2 channel
43
+ runs-on: ubuntu-latest
44
+ steps:
45
+ - name: Set up Python
46
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97
47
+ with:
48
+ python-version: '3.13'
49
+
50
+ - name: Install directly from public stable channel
51
+ run: |
52
+ python -m pip install "git+https://github.com/AETHERXGLOBAL/reprocert.git@v0.2"
53
+ reprocert --version
54
+
55
+ - name: Zero-contact self-service round-trip
56
+ shell: bash
57
+ run: |
58
+ mkdir consumer
59
+ cd consumer
60
+ reprocert init command --github-actions
61
+ reprocert doctor
62
+ reprocert run reprocert.yml -o certificate.json
63
+ reprocert verify certificate.json --claim reprocert.yml --evidence-root .
64
+ grep -q "AETHERXGLOBAL/reprocert@v0.2" .github/workflows/reprocert.yml
@@ -0,0 +1,16 @@
1
+ __pycache__/
2
+ .pytest_cache/
3
+ *.py[cod]
4
+ dist/
5
+ build/
6
+ *.egg-info/
7
+ certificate.json
8
+ reprocert-certificate.json
9
+ reprocert-pytest-certificate.json
10
+ reprocert-policy-result.json
11
+ reprocert-predicate.json
12
+ reprocert-suite-report.json
13
+ result.json
14
+ .reprocert/
15
+ .reprocert-pytest-claim.json
16
+ .reprocert-pytest-junit.xml