dsoxlab 0.1.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.
- dsoxlab-0.1.0/.github/CODEOWNERS +3 -0
- dsoxlab-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +63 -0
- dsoxlab-0.1.0/.github/ISSUE_TEMPLATE/config.yml +8 -0
- dsoxlab-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +36 -0
- dsoxlab-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +26 -0
- dsoxlab-0.1.0/.github/dependabot.yml +22 -0
- dsoxlab-0.1.0/.github/workflows/ci.yml +114 -0
- dsoxlab-0.1.0/.github/workflows/plumber.yml +61 -0
- dsoxlab-0.1.0/.github/workflows/release.yml +93 -0
- dsoxlab-0.1.0/.github/workflows/scorecard.yml +55 -0
- dsoxlab-0.1.0/.gitignore +76 -0
- dsoxlab-0.1.0/.plumber.yaml +1023 -0
- dsoxlab-0.1.0/.pre-commit-config.yaml +66 -0
- dsoxlab-0.1.0/CHANGELOG.fr.md +39 -0
- dsoxlab-0.1.0/CHANGELOG.md +39 -0
- dsoxlab-0.1.0/CODE_OF_CONDUCT.fr.md +71 -0
- dsoxlab-0.1.0/CODE_OF_CONDUCT.md +68 -0
- dsoxlab-0.1.0/CONTRIBUTING.fr.md +139 -0
- dsoxlab-0.1.0/CONTRIBUTING.md +137 -0
- dsoxlab-0.1.0/LICENSE +414 -0
- dsoxlab-0.1.0/PKG-INFO +319 -0
- dsoxlab-0.1.0/README.fr.md +287 -0
- dsoxlab-0.1.0/README.md +284 -0
- dsoxlab-0.1.0/RELEASING.fr.md +46 -0
- dsoxlab-0.1.0/RELEASING.md +45 -0
- dsoxlab-0.1.0/SECURITY.fr.md +44 -0
- dsoxlab-0.1.0/SECURITY.md +42 -0
- dsoxlab-0.1.0/pyproject.toml +115 -0
- dsoxlab-0.1.0/src/dsoxlab/__init__.py +3 -0
- dsoxlab-0.1.0/src/dsoxlab/cli.py +1727 -0
- dsoxlab-0.1.0/src/dsoxlab/config.py +159 -0
- dsoxlab-0.1.0/src/dsoxlab/discovery/__init__.py +10 -0
- dsoxlab-0.1.0/src/dsoxlab/discovery/repo.py +84 -0
- dsoxlab-0.1.0/src/dsoxlab/discovery/scanner.py +137 -0
- dsoxlab-0.1.0/src/dsoxlab/i18n/__init__.py +77 -0
- dsoxlab-0.1.0/src/dsoxlab/i18n/strings/__init__.py +0 -0
- dsoxlab-0.1.0/src/dsoxlab/i18n/strings/en.py +411 -0
- dsoxlab-0.1.0/src/dsoxlab/i18n/strings/fr.py +408 -0
- dsoxlab-0.1.0/src/dsoxlab/infra/__init__.py +45 -0
- dsoxlab-0.1.0/src/dsoxlab/infra/ansible.py +216 -0
- dsoxlab-0.1.0/src/dsoxlab/infra/credentials.py +274 -0
- dsoxlab-0.1.0/src/dsoxlab/infra/inventory.py +314 -0
- dsoxlab-0.1.0/src/dsoxlab/infra/snapshot/__init__.py +90 -0
- dsoxlab-0.1.0/src/dsoxlab/infra/snapshot/kvm.py +89 -0
- dsoxlab-0.1.0/src/dsoxlab/infra/terraform.py +520 -0
- dsoxlab-0.1.0/src/dsoxlab/models/__init__.py +27 -0
- dsoxlab-0.1.0/src/dsoxlab/models/course.py +73 -0
- dsoxlab-0.1.0/src/dsoxlab/models/hint.py +87 -0
- dsoxlab-0.1.0/src/dsoxlab/models/lab.py +127 -0
- dsoxlab-0.1.0/src/dsoxlab/models/repo.py +367 -0
- dsoxlab-0.1.0/src/dsoxlab/models/runtime.py +129 -0
- dsoxlab-0.1.0/src/dsoxlab/py.typed +0 -0
- dsoxlab-0.1.0/src/dsoxlab/reporting/__init__.py +49 -0
- dsoxlab-0.1.0/src/dsoxlab/reporting/console.py +540 -0
- dsoxlab-0.1.0/src/dsoxlab/runtimes/__init__.py +8 -0
- dsoxlab-0.1.0/src/dsoxlab/runtimes/base.py +69 -0
- dsoxlab-0.1.0/src/dsoxlab/runtimes/manager.py +35 -0
- dsoxlab-0.1.0/src/dsoxlab/runtimes/shell.py +133 -0
- dsoxlab-0.1.0/src/dsoxlab/runtimes/vm.py +280 -0
- dsoxlab-0.1.0/src/dsoxlab/services/__init__.py +31 -0
- dsoxlab-0.1.0/src/dsoxlab/services/lab_service.py +292 -0
- dsoxlab-0.1.0/src/dsoxlab/sessions/__init__.py +1 -0
- dsoxlab-0.1.0/src/dsoxlab/sessions/store.py +167 -0
- dsoxlab-0.1.0/src/dsoxlab/templates/__init__.py +82 -0
- dsoxlab-0.1.0/src/dsoxlab/templates/cloud-init/almalinux.yaml.tmpl +62 -0
- dsoxlab-0.1.0/src/dsoxlab/templates/cloud-init/ubuntu.yaml.tmpl +62 -0
- dsoxlab-0.1.0/src/dsoxlab/templates/terraform/README.md +121 -0
- dsoxlab-0.1.0/src/dsoxlab/templates/terraform/incus/main.tf +194 -0
- dsoxlab-0.1.0/src/dsoxlab/templates/terraform/incus/outputs.tf +14 -0
- dsoxlab-0.1.0/src/dsoxlab/templates/terraform/incus/variables.tf +28 -0
- dsoxlab-0.1.0/src/dsoxlab/templates/terraform/incus/versions.tf +15 -0
- dsoxlab-0.1.0/src/dsoxlab/templates/terraform/kvm/main.tf +388 -0
- dsoxlab-0.1.0/src/dsoxlab/templates/terraform/kvm/outputs.tf +14 -0
- dsoxlab-0.1.0/src/dsoxlab/templates/terraform/kvm/variables.tf +28 -0
- dsoxlab-0.1.0/src/dsoxlab/templates/terraform/kvm/versions.tf +14 -0
- dsoxlab-0.1.0/src/dsoxlab/templates/terraform/outscale/main.tf +380 -0
- dsoxlab-0.1.0/src/dsoxlab/templates/terraform/outscale/outputs.tf +20 -0
- dsoxlab-0.1.0/src/dsoxlab/templates/terraform/outscale/variables.tf +41 -0
- dsoxlab-0.1.0/src/dsoxlab/templates/terraform/outscale/versions.tf +18 -0
- dsoxlab-0.1.0/src/dsoxlab/utils/__init__.py +5 -0
- dsoxlab-0.1.0/src/dsoxlab/utils/shell.py +91 -0
- dsoxlab-0.1.0/src/dsoxlab/validators/__init__.py +6 -0
- dsoxlab-0.1.0/src/dsoxlab/validators/metadata.py +59 -0
- dsoxlab-0.1.0/src/dsoxlab/validators/structure.py +144 -0
- dsoxlab-0.1.0/tests/__init__.py +0 -0
- dsoxlab-0.1.0/tests/test_cli_smoke.py +32 -0
- dsoxlab-0.1.0/uv.lock +641 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Report a defect in the dsoxlab CLI
|
|
3
|
+
labels: ["bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
Thanks for taking the time to report a bug. Please fill in the fields
|
|
9
|
+
below so we can reproduce and fix it quickly.
|
|
10
|
+
For security issues, do not open a public issue — see SECURITY.md.
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: what-happened
|
|
13
|
+
attributes:
|
|
14
|
+
label: What happened
|
|
15
|
+
description: A clear description of the bug and what you expected instead.
|
|
16
|
+
placeholder: When I run `dsoxlab check ...`, it fails with ...
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
- type: textarea
|
|
20
|
+
id: reproduce
|
|
21
|
+
attributes:
|
|
22
|
+
label: Steps to reproduce
|
|
23
|
+
description: The exact commands, run from which directory / lab repository.
|
|
24
|
+
placeholder: |
|
|
25
|
+
1. cd ~/Projets/linux-training
|
|
26
|
+
2. dsoxlab run linux.depanner.service-crash-loop
|
|
27
|
+
3. ...
|
|
28
|
+
validations:
|
|
29
|
+
required: true
|
|
30
|
+
- type: input
|
|
31
|
+
id: version
|
|
32
|
+
attributes:
|
|
33
|
+
label: dsoxlab version
|
|
34
|
+
description: Output of `dsoxlab --version`.
|
|
35
|
+
placeholder: dsoxlab 0.1.0
|
|
36
|
+
validations:
|
|
37
|
+
required: true
|
|
38
|
+
- type: input
|
|
39
|
+
id: os
|
|
40
|
+
attributes:
|
|
41
|
+
label: Operating system
|
|
42
|
+
placeholder: Ubuntu 24.04 / Fedora 41 / ...
|
|
43
|
+
validations:
|
|
44
|
+
required: true
|
|
45
|
+
- type: dropdown
|
|
46
|
+
id: runtime
|
|
47
|
+
attributes:
|
|
48
|
+
label: Runtime involved
|
|
49
|
+
options:
|
|
50
|
+
- shell
|
|
51
|
+
- incus
|
|
52
|
+
- kvm
|
|
53
|
+
- not applicable
|
|
54
|
+
validations:
|
|
55
|
+
required: false
|
|
56
|
+
- type: textarea
|
|
57
|
+
id: logs
|
|
58
|
+
attributes:
|
|
59
|
+
label: Logs / output
|
|
60
|
+
description: Relevant output. This will be rendered as code, no backticks needed.
|
|
61
|
+
render: shell
|
|
62
|
+
validations:
|
|
63
|
+
required: false
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Documentation and tutorials
|
|
4
|
+
url: https://blog.stephane-robert.info
|
|
5
|
+
about: Guides and lab walkthroughs on the author's blog.
|
|
6
|
+
- name: Security report
|
|
7
|
+
url: https://github.com/stephrobert/dsoxlab/security/advisories/new
|
|
8
|
+
about: Report a vulnerability privately instead of opening a public issue.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Suggest an idea or improvement for dsoxlab
|
|
3
|
+
labels: ["enhancement"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
Remember the golden rule: the engine stays domain-agnostic. Domain
|
|
9
|
+
logic belongs in a lab repository's contract, not in dsoxlab itself.
|
|
10
|
+
- type: textarea
|
|
11
|
+
id: problem
|
|
12
|
+
attributes:
|
|
13
|
+
label: Problem to solve
|
|
14
|
+
description: What are you trying to do that is hard or impossible today?
|
|
15
|
+
validations:
|
|
16
|
+
required: true
|
|
17
|
+
- type: textarea
|
|
18
|
+
id: proposal
|
|
19
|
+
attributes:
|
|
20
|
+
label: Proposed solution
|
|
21
|
+
description: How could dsoxlab solve it? CLI command, contract field, runtime…
|
|
22
|
+
validations:
|
|
23
|
+
required: true
|
|
24
|
+
- type: textarea
|
|
25
|
+
id: alternatives
|
|
26
|
+
attributes:
|
|
27
|
+
label: Alternatives considered
|
|
28
|
+
validations:
|
|
29
|
+
required: false
|
|
30
|
+
- type: checkboxes
|
|
31
|
+
id: agnostic
|
|
32
|
+
attributes:
|
|
33
|
+
label: Domain-agnostic check
|
|
34
|
+
options:
|
|
35
|
+
- label: This request keeps the engine free of domain-specific logic.
|
|
36
|
+
required: true
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Summary
|
|
2
|
+
|
|
3
|
+
<!-- What does this PR change and why? -->
|
|
4
|
+
|
|
5
|
+
## Type of change
|
|
6
|
+
|
|
7
|
+
- [ ] Bug fix
|
|
8
|
+
- [ ] New feature
|
|
9
|
+
- [ ] Refactor
|
|
10
|
+
- [ ] Documentation
|
|
11
|
+
- [ ] Chore / tooling
|
|
12
|
+
|
|
13
|
+
## Checklist
|
|
14
|
+
|
|
15
|
+
- [ ] `uv run ruff check src/dsoxlab` passes
|
|
16
|
+
- [ ] `uv run mypy src/dsoxlab` passes (strict)
|
|
17
|
+
- [ ] `uv run pytest` passes
|
|
18
|
+
- [ ] The engine stays domain-agnostic (no domain-specific logic in `src/dsoxlab/`)
|
|
19
|
+
- [ ] New/changed user-facing strings are added to **both** `i18n/strings/en.py` and `i18n/strings/fr.py`
|
|
20
|
+
- [ ] New/changed command or option is reflected in its `help=_()`, the i18n keys, and `fullhelp` (EN + FR)
|
|
21
|
+
- [ ] `CHANGELOG.md` updated when behavior changes
|
|
22
|
+
- [ ] Manually tested against at least one lab repository
|
|
23
|
+
|
|
24
|
+
## Related issues
|
|
25
|
+
|
|
26
|
+
<!-- e.g. Closes #123 -->
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: "uv"
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: "weekly"
|
|
7
|
+
open-pull-requests-limit: 5
|
|
8
|
+
commit-message:
|
|
9
|
+
prefix: "chore(deps)"
|
|
10
|
+
# Wait before proposing a brand-new release: a compromised package is
|
|
11
|
+
# usually yanked within days, so a cooldown shrinks the exposure window.
|
|
12
|
+
cooldown:
|
|
13
|
+
default-days: 7
|
|
14
|
+
|
|
15
|
+
- package-ecosystem: "github-actions"
|
|
16
|
+
directory: "/"
|
|
17
|
+
schedule:
|
|
18
|
+
interval: "weekly"
|
|
19
|
+
commit-message:
|
|
20
|
+
prefix: "chore(ci)"
|
|
21
|
+
cooldown:
|
|
22
|
+
default-days: 7
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Contribution gate. zizmor statically analyzes the workflows first, as a fast
|
|
2
|
+
# security gate; the heavier jobs (quality matrix, CodeQL) only run once it
|
|
3
|
+
# passes, so an insecure workflow fails fast without burning runners.
|
|
4
|
+
#
|
|
5
|
+
# Deeper CI/CD policy scanning and the compliance score live in plumber.yml
|
|
6
|
+
# (trusted context only); supply-chain posture in scorecard.yml.
|
|
7
|
+
#
|
|
8
|
+
# Hardening baseline: every action is pinned to a full commit SHA, the default
|
|
9
|
+
# token has no permissions, each job grants only what it needs, checkout never
|
|
10
|
+
# persists credentials, and jobs are time-boxed.
|
|
11
|
+
name: CI
|
|
12
|
+
|
|
13
|
+
on:
|
|
14
|
+
push:
|
|
15
|
+
branches: [main]
|
|
16
|
+
pull_request:
|
|
17
|
+
branches: [main]
|
|
18
|
+
|
|
19
|
+
# Deny-by-default: jobs opt into the scopes they need, nothing is inherited.
|
|
20
|
+
permissions: {}
|
|
21
|
+
|
|
22
|
+
concurrency:
|
|
23
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
24
|
+
cancel-in-progress: true
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
# Fast security gate — the quality and CodeQL jobs depend on it.
|
|
28
|
+
zizmor:
|
|
29
|
+
name: Zizmor (workflow static analysis)
|
|
30
|
+
runs-on: ubuntu-24.04
|
|
31
|
+
timeout-minutes: 10
|
|
32
|
+
permissions:
|
|
33
|
+
contents: read
|
|
34
|
+
steps:
|
|
35
|
+
- name: Checkout
|
|
36
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
37
|
+
with:
|
|
38
|
+
persist-credentials: false
|
|
39
|
+
|
|
40
|
+
# Gate-only (no SARIF upload) so the check also passes on pull requests
|
|
41
|
+
# from forks, where the token cannot write to code scanning. Findings in
|
|
42
|
+
# the Security tab come from CodeQL and plumber.yml on same-repo events.
|
|
43
|
+
- name: Zizmor
|
|
44
|
+
uses: zizmorcore/zizmor-action@192e21d79ab29983730a13d1382995c2307fbcaa # v0.5.7
|
|
45
|
+
with:
|
|
46
|
+
version: "1.26.1"
|
|
47
|
+
advanced-security: false
|
|
48
|
+
|
|
49
|
+
quality:
|
|
50
|
+
name: Lint, type-check and test (py${{ matrix.python-version }})
|
|
51
|
+
needs: zizmor
|
|
52
|
+
runs-on: ubuntu-24.04
|
|
53
|
+
timeout-minutes: 15
|
|
54
|
+
permissions:
|
|
55
|
+
contents: read
|
|
56
|
+
strategy:
|
|
57
|
+
fail-fast: false
|
|
58
|
+
matrix:
|
|
59
|
+
python-version: ['3.11', '3.12', '3.13']
|
|
60
|
+
env:
|
|
61
|
+
# Passed through the environment (not template-expanded into run blocks)
|
|
62
|
+
# so no context value is ever interpolated into shell code.
|
|
63
|
+
PYTHON_VERSION: ${{ matrix.python-version }}
|
|
64
|
+
steps:
|
|
65
|
+
- name: Checkout
|
|
66
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
67
|
+
with:
|
|
68
|
+
persist-credentials: false
|
|
69
|
+
|
|
70
|
+
- name: Install uv
|
|
71
|
+
uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
|
|
72
|
+
with:
|
|
73
|
+
version: "0.11.26"
|
|
74
|
+
enable-cache: true
|
|
75
|
+
|
|
76
|
+
- name: Install Python ${{ matrix.python-version }}
|
|
77
|
+
run: uv python install "$PYTHON_VERSION"
|
|
78
|
+
|
|
79
|
+
- name: Sync dependencies (locked)
|
|
80
|
+
run: uv sync --frozen --python "$PYTHON_VERSION"
|
|
81
|
+
|
|
82
|
+
- name: Lint and security (ruff)
|
|
83
|
+
run: uv run ruff check src/dsoxlab tests
|
|
84
|
+
|
|
85
|
+
- name: Type-check (mypy strict)
|
|
86
|
+
run: uv run mypy src/dsoxlab
|
|
87
|
+
|
|
88
|
+
- name: Test (pytest)
|
|
89
|
+
run: uv run pytest
|
|
90
|
+
|
|
91
|
+
codeql:
|
|
92
|
+
name: CodeQL analyze (python)
|
|
93
|
+
needs: zizmor
|
|
94
|
+
runs-on: ubuntu-24.04
|
|
95
|
+
timeout-minutes: 20
|
|
96
|
+
permissions:
|
|
97
|
+
contents: read
|
|
98
|
+
security-events: write # upload the CodeQL results to Code Scanning
|
|
99
|
+
steps:
|
|
100
|
+
- name: Checkout
|
|
101
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
102
|
+
with:
|
|
103
|
+
persist-credentials: false
|
|
104
|
+
|
|
105
|
+
- name: Initialize CodeQL
|
|
106
|
+
uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
|
|
107
|
+
with:
|
|
108
|
+
languages: python
|
|
109
|
+
build-mode: none # Python is interpreted, no build step to observe
|
|
110
|
+
|
|
111
|
+
- name: Perform CodeQL analysis
|
|
112
|
+
uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
|
|
113
|
+
with:
|
|
114
|
+
category: "/language:python"
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Validates dsoxlab's own CI/CD with Plumber (getplumber.io): it analyzes the
|
|
2
|
+
# repo's GitHub Actions workflows and repository settings against .plumber.yaml,
|
|
3
|
+
# uploads findings to Code Scanning, publishes the compliance score to the
|
|
4
|
+
# README badge, and fails below the threshold. The action verifies the
|
|
5
|
+
# downloaded Plumber binary's SLSA build-provenance attestation before running.
|
|
6
|
+
#
|
|
7
|
+
# This workflow runs ONLY in trusted contexts (push to main, schedule, manual):
|
|
8
|
+
# it needs a privileged token (Administration:read) to verify branch protection,
|
|
9
|
+
# and that secret must never be exposed to pull_request runs — especially from
|
|
10
|
+
# forks. Pull requests are gated for workflow security by zizmor in ci.yml,
|
|
11
|
+
# which uses no secrets.
|
|
12
|
+
name: Plumber compliance
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
push:
|
|
16
|
+
branches: [main]
|
|
17
|
+
schedule:
|
|
18
|
+
- cron: '30 2 * * 1'
|
|
19
|
+
workflow_dispatch:
|
|
20
|
+
|
|
21
|
+
permissions: {}
|
|
22
|
+
|
|
23
|
+
concurrency:
|
|
24
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
25
|
+
cancel-in-progress: true
|
|
26
|
+
|
|
27
|
+
jobs:
|
|
28
|
+
plumber:
|
|
29
|
+
name: Plumber analyze
|
|
30
|
+
# Skips while private (SARIF upload needs Advanced Security, free on public
|
|
31
|
+
# repos); activates automatically once the repo is public.
|
|
32
|
+
if: ${{ !github.event.repository.private }}
|
|
33
|
+
runs-on: ubuntu-24.04
|
|
34
|
+
timeout-minutes: 10
|
|
35
|
+
# The privileged token lives in this protected environment, which is
|
|
36
|
+
# restricted to the main branch — it is unreachable from pull_request runs.
|
|
37
|
+
environment: security
|
|
38
|
+
permissions:
|
|
39
|
+
contents: read
|
|
40
|
+
security-events: write # upload SARIF to Code Scanning
|
|
41
|
+
actions: read # read the workflow run for Plumber status
|
|
42
|
+
id-token: write # OIDC to publish the score to score.getplumber.io
|
|
43
|
+
steps:
|
|
44
|
+
- name: Checkout
|
|
45
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
46
|
+
with:
|
|
47
|
+
persist-credentials: false
|
|
48
|
+
|
|
49
|
+
- name: Plumber compliance scan
|
|
50
|
+
uses: getplumber/plumber@fdd2a2d0555bb3b33cbb2efff3b955dea5a6bbf0 # v0.4.3
|
|
51
|
+
with:
|
|
52
|
+
version: "v0.4.3"
|
|
53
|
+
verify-attestation: "true" # check the binary's SLSA provenance before running
|
|
54
|
+
threshold: "100"
|
|
55
|
+
upload-sarif: "true"
|
|
56
|
+
upload-artifacts: "true"
|
|
57
|
+
score-push: "true" # publish the score to the README badge
|
|
58
|
+
# Fine-grained PAT (Administration + Contents + Metadata = Read),
|
|
59
|
+
# stored as an environment secret in the protected `security`
|
|
60
|
+
# environment, so branchMustBeProtected is verified for real.
|
|
61
|
+
github-token: ${{ secrets.PLUMBER_ADMIN_TOKEN }}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Publish dsoxlab to PyPI when a version tag (vX.Y.Z) is pushed.
|
|
2
|
+
#
|
|
3
|
+
# Security model:
|
|
4
|
+
# - PyPI Trusted Publishing (OIDC). No API token or long-lived secret: the
|
|
5
|
+
# `publish` job mints a short-lived id-token that PyPI trusts. Configure the
|
|
6
|
+
# trusted publisher on PyPI (project: dsoxlab, workflow: release.yml,
|
|
7
|
+
# environment: pypi) before the first release.
|
|
8
|
+
# - Privilege separation: `build` compiles the artifacts with read-only access
|
|
9
|
+
# and runs project code; `publish` runs no project code, only downloads the
|
|
10
|
+
# built artifacts and hands them to PyPI with `id-token: write`.
|
|
11
|
+
# - The `pypi` GitHub Environment gates the publish step (add required
|
|
12
|
+
# reviewers / tag protection there for a manual approval before upload).
|
|
13
|
+
# - Every action is pinned to a full commit SHA; the default token has no
|
|
14
|
+
# permissions; no build cache in the publishing path (cache-poisoning
|
|
15
|
+
# hardening).
|
|
16
|
+
name: Release
|
|
17
|
+
|
|
18
|
+
on:
|
|
19
|
+
push:
|
|
20
|
+
tags:
|
|
21
|
+
- 'v*'
|
|
22
|
+
|
|
23
|
+
permissions: {}
|
|
24
|
+
|
|
25
|
+
concurrency:
|
|
26
|
+
group: release-${{ github.ref }}
|
|
27
|
+
cancel-in-progress: false
|
|
28
|
+
|
|
29
|
+
jobs:
|
|
30
|
+
build:
|
|
31
|
+
name: Build distribution
|
|
32
|
+
runs-on: ubuntu-24.04
|
|
33
|
+
timeout-minutes: 10
|
|
34
|
+
permissions:
|
|
35
|
+
contents: read
|
|
36
|
+
id-token: write # mint the OIDC token used to sign the provenance
|
|
37
|
+
attestations: write # record the SLSA build provenance for the artifacts
|
|
38
|
+
steps:
|
|
39
|
+
- name: Checkout
|
|
40
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
41
|
+
with:
|
|
42
|
+
persist-credentials: false
|
|
43
|
+
|
|
44
|
+
- name: Install uv
|
|
45
|
+
uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
|
|
46
|
+
with:
|
|
47
|
+
version: "0.11.26"
|
|
48
|
+
enable-cache: false # no cache in the publishing path (cache-poisoning hardening)
|
|
49
|
+
|
|
50
|
+
- name: Build sdist and wheel
|
|
51
|
+
run: uv build
|
|
52
|
+
|
|
53
|
+
- name: Check distribution metadata
|
|
54
|
+
run: uvx twine check dist/*
|
|
55
|
+
|
|
56
|
+
# SLSA build provenance for the wheel and sdist, verifiable with
|
|
57
|
+
# `gh attestation verify <artifact> --repo stephrobert/dsoxlab` or
|
|
58
|
+
# slsa-verifier. Complements the PEP 740 attestations PyPI records.
|
|
59
|
+
- name: Attest build provenance
|
|
60
|
+
uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1
|
|
61
|
+
with:
|
|
62
|
+
subject-path: 'dist/*'
|
|
63
|
+
|
|
64
|
+
- name: Upload distribution artifact
|
|
65
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
66
|
+
with:
|
|
67
|
+
name: dist
|
|
68
|
+
path: dist/
|
|
69
|
+
if-no-files-found: error
|
|
70
|
+
retention-days: 1
|
|
71
|
+
|
|
72
|
+
publish:
|
|
73
|
+
name: Publish to PyPI
|
|
74
|
+
needs: build
|
|
75
|
+
runs-on: ubuntu-24.04
|
|
76
|
+
timeout-minutes: 10
|
|
77
|
+
environment:
|
|
78
|
+
name: pypi
|
|
79
|
+
url: https://pypi.org/p/dsoxlab
|
|
80
|
+
permissions:
|
|
81
|
+
id-token: write # OIDC token for Trusted Publishing — the only scope needed
|
|
82
|
+
steps:
|
|
83
|
+
- name: Download distribution artifact
|
|
84
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
85
|
+
with:
|
|
86
|
+
name: dist
|
|
87
|
+
path: dist/
|
|
88
|
+
|
|
89
|
+
- name: Publish to PyPI (Trusted Publishing)
|
|
90
|
+
uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
|
|
91
|
+
with:
|
|
92
|
+
attestations: true
|
|
93
|
+
print-hash: true
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# OpenSSF Scorecard: measures the repository's supply-chain security posture
|
|
2
|
+
# (branch protection, pinned dependencies, token permissions, code review, …)
|
|
3
|
+
# and publishes the result to the public Scorecard viewer and the README badge.
|
|
4
|
+
name: OpenSSF Scorecard
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches: [main]
|
|
9
|
+
branch_protection_rule:
|
|
10
|
+
schedule:
|
|
11
|
+
- cron: '30 1 * * 1'
|
|
12
|
+
workflow_dispatch:
|
|
13
|
+
|
|
14
|
+
permissions: {}
|
|
15
|
+
|
|
16
|
+
concurrency:
|
|
17
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
18
|
+
cancel-in-progress: true
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
analysis:
|
|
22
|
+
name: Scorecard analysis
|
|
23
|
+
# Scorecard needs a public repository (commit-graph API + result
|
|
24
|
+
# publication). Skips while private (pre-launch); activates once public.
|
|
25
|
+
if: ${{ !github.event.repository.private }}
|
|
26
|
+
runs-on: ubuntu-24.04
|
|
27
|
+
timeout-minutes: 10
|
|
28
|
+
permissions:
|
|
29
|
+
contents: read
|
|
30
|
+
security-events: write # upload SARIF to Code Scanning
|
|
31
|
+
id-token: write # publish results to the OpenSSF Scorecard API
|
|
32
|
+
steps:
|
|
33
|
+
- name: Checkout
|
|
34
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
35
|
+
with:
|
|
36
|
+
persist-credentials: false
|
|
37
|
+
|
|
38
|
+
- name: Run Scorecard
|
|
39
|
+
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
|
|
40
|
+
with:
|
|
41
|
+
results_file: results.sarif
|
|
42
|
+
results_format: sarif
|
|
43
|
+
publish_results: true
|
|
44
|
+
|
|
45
|
+
- name: Upload SARIF to Code Scanning
|
|
46
|
+
uses: github/codeql-action/upload-sarif@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
|
|
47
|
+
with:
|
|
48
|
+
sarif_file: results.sarif
|
|
49
|
+
|
|
50
|
+
- name: Upload artifact
|
|
51
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
52
|
+
with:
|
|
53
|
+
name: scorecard-results
|
|
54
|
+
path: results.sarif
|
|
55
|
+
retention-days: 5
|
dsoxlab-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
*.egg-info/
|
|
20
|
+
.installed.cfg
|
|
21
|
+
*.egg
|
|
22
|
+
|
|
23
|
+
# Virtualenv
|
|
24
|
+
.venv/
|
|
25
|
+
venv/
|
|
26
|
+
env/
|
|
27
|
+
ENV/
|
|
28
|
+
|
|
29
|
+
# uv
|
|
30
|
+
.uv/
|
|
31
|
+
|
|
32
|
+
# pytest
|
|
33
|
+
.pytest_cache/
|
|
34
|
+
.coverage
|
|
35
|
+
htmlcov/
|
|
36
|
+
.tox/
|
|
37
|
+
.cache/
|
|
38
|
+
|
|
39
|
+
# mypy
|
|
40
|
+
.mypy_cache/
|
|
41
|
+
.dmypy.json
|
|
42
|
+
|
|
43
|
+
# Ruff
|
|
44
|
+
.ruff_cache/
|
|
45
|
+
|
|
46
|
+
# IDE
|
|
47
|
+
.vscode/
|
|
48
|
+
.idea/
|
|
49
|
+
*.swp
|
|
50
|
+
*.swo
|
|
51
|
+
*~
|
|
52
|
+
.DS_Store
|
|
53
|
+
|
|
54
|
+
# OS
|
|
55
|
+
Thumbs.db
|
|
56
|
+
|
|
57
|
+
# Local agent / editor tooling (machine-specific, not for the public repo)
|
|
58
|
+
.claude/
|
|
59
|
+
CLAUDE.md
|
|
60
|
+
|
|
61
|
+
# Task/todo scratch — never published
|
|
62
|
+
todos/
|
|
63
|
+
.todos/
|
|
64
|
+
TODO/
|
|
65
|
+
todo/
|
|
66
|
+
|
|
67
|
+
# Build metadata
|
|
68
|
+
*.egg-info/
|
|
69
|
+
|
|
70
|
+
# dsoxlab — état runtime local (jamais versionné)
|
|
71
|
+
.dsoxlab-context.json
|
|
72
|
+
.dsoxlab.db
|
|
73
|
+
|
|
74
|
+
# Terraform validate artefacts dans les templates packagés (non committables)
|
|
75
|
+
src/dsoxlab/templates/terraform/*/.terraform/
|
|
76
|
+
src/dsoxlab/templates/terraform/*/.terraform.lock.hcl
|