docsmoke 1.0.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.
Files changed (59) hide show
  1. docsmoke-1.0.0/.dockerignore +11 -0
  2. docsmoke-1.0.0/.github/CODEOWNERS +1 -0
  3. docsmoke-1.0.0/.github/FUNDING.yml +1 -0
  4. docsmoke-1.0.0/.github/ISSUE_TEMPLATE/bug_report.yml +31 -0
  5. docsmoke-1.0.0/.github/ISSUE_TEMPLATE/config.yml +8 -0
  6. docsmoke-1.0.0/.github/ISSUE_TEMPLATE/feature_request.yml +31 -0
  7. docsmoke-1.0.0/.github/PULL_REQUEST_TEMPLATE.md +14 -0
  8. docsmoke-1.0.0/.github/dependabot.yml +13 -0
  9. docsmoke-1.0.0/.github/workflows/ci.yml +84 -0
  10. docsmoke-1.0.0/.github/workflows/pages.yml +48 -0
  11. docsmoke-1.0.0/.github/workflows/release.yml +162 -0
  12. docsmoke-1.0.0/.gitignore +13 -0
  13. docsmoke-1.0.0/.pre-commit-config.yaml +42 -0
  14. docsmoke-1.0.0/CHANGELOG.md +28 -0
  15. docsmoke-1.0.0/CODE_OF_CONDUCT.md +45 -0
  16. docsmoke-1.0.0/CONTRIBUTING.md +43 -0
  17. docsmoke-1.0.0/Dockerfile +30 -0
  18. docsmoke-1.0.0/LICENSE +201 -0
  19. docsmoke-1.0.0/Makefile +54 -0
  20. docsmoke-1.0.0/NOTICE +10 -0
  21. docsmoke-1.0.0/PKG-INFO +359 -0
  22. docsmoke-1.0.0/README.md +114 -0
  23. docsmoke-1.0.0/SECURITY.md +16 -0
  24. docsmoke-1.0.0/SUPPORT.md +43 -0
  25. docsmoke-1.0.0/action.yml +110 -0
  26. docsmoke-1.0.0/docs/ARCHITECTURE.md +30 -0
  27. docsmoke-1.0.0/docs/CONFIG.md +26 -0
  28. docsmoke-1.0.0/docs/INSTALL.md +39 -0
  29. docsmoke-1.0.0/docs/RELEASE.md +155 -0
  30. docsmoke-1.0.0/docs/REPOSITORY.md +85 -0
  31. docsmoke-1.0.0/docs/USAGE.md +48 -0
  32. docsmoke-1.0.0/docs/site/.nojekyll +0 -0
  33. docsmoke-1.0.0/docs/site/assets/site.css +92 -0
  34. docsmoke-1.0.0/docs/site/index.html +66 -0
  35. docsmoke-1.0.0/examples/README.md +8 -0
  36. docsmoke-1.0.0/examples/docsmoke.toml +5 -0
  37. docsmoke-1.0.0/pyproject.toml +156 -0
  38. docsmoke-1.0.0/src/docsmoke/__init__.py +12 -0
  39. docsmoke-1.0.0/src/docsmoke/__main__.py +3 -0
  40. docsmoke-1.0.0/src/docsmoke/cli.py +184 -0
  41. docsmoke-1.0.0/src/docsmoke/config.py +98 -0
  42. docsmoke-1.0.0/src/docsmoke/exceptions.py +13 -0
  43. docsmoke-1.0.0/src/docsmoke/executor.py +162 -0
  44. docsmoke-1.0.0/src/docsmoke/markdown.py +211 -0
  45. docsmoke-1.0.0/src/docsmoke/models.py +133 -0
  46. docsmoke-1.0.0/src/docsmoke/py.typed +0 -0
  47. docsmoke-1.0.0/src/docsmoke/reporting/__init__.py +32 -0
  48. docsmoke-1.0.0/src/docsmoke/reporting/console.py +42 -0
  49. docsmoke-1.0.0/src/docsmoke/reporting/json.py +13 -0
  50. docsmoke-1.0.0/src/docsmoke/reporting/markdown.py +43 -0
  51. docsmoke-1.0.0/src/docsmoke/runner.py +78 -0
  52. docsmoke-1.0.0/tests/__init__.py +0 -0
  53. docsmoke-1.0.0/tests/test_cli.py +130 -0
  54. docsmoke-1.0.0/tests/test_config.py +126 -0
  55. docsmoke-1.0.0/tests/test_docs_links.py +98 -0
  56. docsmoke-1.0.0/tests/test_executor.py +238 -0
  57. docsmoke-1.0.0/tests/test_markdown.py +310 -0
  58. docsmoke-1.0.0/tests/test_reporting.py +75 -0
  59. docsmoke-1.0.0/tests/test_runner.py +118 -0
@@ -0,0 +1,11 @@
1
+ .git
2
+ .github
3
+ .DS_Store
4
+ .mypy_cache
5
+ .pytest_cache
6
+ .ruff_cache
7
+ .venv
8
+ build
9
+ dist
10
+ htmlcov
11
+ tests
@@ -0,0 +1 @@
1
+ * @dev-ugurkontel
@@ -0,0 +1 @@
1
+ github: [dev-ugurkontel]
@@ -0,0 +1,31 @@
1
+ name: Bug report
2
+ description: Report a defect in docsmoke.
3
+ labels: ["bug", "needs-triage"]
4
+ body:
5
+ - type: textarea
6
+ id: summary
7
+ attributes:
8
+ label: Summary
9
+ description: What happened?
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: reproduction
14
+ attributes:
15
+ label: Steps to reproduce
16
+ render: bash
17
+ validations:
18
+ required: true
19
+ - type: textarea
20
+ id: expected
21
+ attributes:
22
+ label: Expected behavior
23
+ validations:
24
+ required: true
25
+ - type: input
26
+ id: version
27
+ attributes:
28
+ label: docsmoke version
29
+ placeholder: "1.0.0"
30
+ validations:
31
+ required: true
@@ -0,0 +1,8 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: Security vulnerability (private)
4
+ url: https://github.com/dev-ugurkontel/docsmoke/security/advisories/new
5
+ about: For vulnerabilities in docsmoke itself, please report privately.
6
+ - name: Discussions
7
+ url: https://github.com/dev-ugurkontel/docsmoke/discussions
8
+ about: Ask questions and share ideas.
@@ -0,0 +1,31 @@
1
+ name: Feature request
2
+ description: Propose a new capability or improvement.
3
+ labels: ["enhancement", "needs-triage"]
4
+ body:
5
+ - type: textarea
6
+ id: problem
7
+ attributes:
8
+ label: Problem statement
9
+ description: What workflow is currently painful or missing?
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: proposal
14
+ attributes:
15
+ label: Proposed solution
16
+ description: What would you like docsmoke to do?
17
+ validations:
18
+ required: true
19
+ - type: dropdown
20
+ id: area
21
+ attributes:
22
+ label: Area
23
+ options:
24
+ - Discovery
25
+ - Executor
26
+ - Reporting
27
+ - Configuration
28
+ - Documentation
29
+ - CI / GitHub Action
30
+ validations:
31
+ required: true
@@ -0,0 +1,14 @@
1
+ ## Summary
2
+
3
+ Explain what changed and why.
4
+
5
+ ## Checklist
6
+
7
+ - [ ] `make all` passes locally
8
+ - [ ] Tests were added or updated when needed
9
+ - [ ] Docs were updated for user-facing behavior
10
+ - [ ] `CHANGELOG.md` includes an `[Unreleased]` entry when appropriate
11
+
12
+ ## Notes
13
+
14
+ Trade-offs, follow-up work, or rollout details.
@@ -0,0 +1,13 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: pip
4
+ directory: "/"
5
+ schedule:
6
+ interval: weekly
7
+ open-pull-requests-limit: 5
8
+
9
+ - package-ecosystem: github-actions
10
+ directory: "/"
11
+ schedule:
12
+ interval: weekly
13
+ open-pull-requests-limit: 5
@@ -0,0 +1,84 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ concurrency:
13
+ group: ${{ github.workflow }}-${{ github.ref }}
14
+ cancel-in-progress: true
15
+
16
+ # Actions are pinned to immutable commit SHAs per GitHub's security
17
+ # hardening guidance. Comments retain the human-readable upstream
18
+ # version so Dependabot updates stay reviewable.
19
+
20
+ jobs:
21
+ test:
22
+ name: Python ${{ matrix.python-version }}
23
+ runs-on: ubuntu-latest
24
+ timeout-minutes: 15
25
+ strategy:
26
+ fail-fast: false
27
+ matrix:
28
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
29
+ steps:
30
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
31
+
32
+ - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
33
+ with:
34
+ python-version: ${{ matrix.python-version }}
35
+ cache: pip
36
+ cache-dependency-path: pyproject.toml
37
+
38
+ - name: Install project
39
+ run: |
40
+ python -m pip install --upgrade pip
41
+ pip install -e ".[dev]"
42
+
43
+ - name: Lint
44
+ run: ruff check .
45
+
46
+ - name: Format check
47
+ run: ruff format --check .
48
+
49
+ - name: Type check
50
+ run: mypy src
51
+
52
+ - name: Security static analysis
53
+ run: bandit -q -r src -c pyproject.toml
54
+
55
+ - name: Tests
56
+ run: pytest --cov=docsmoke --cov-report=xml --cov-fail-under=100
57
+
58
+ - name: Self-check docs
59
+ run: docsmoke scan README.md docs examples
60
+
61
+ - name: Upload coverage
62
+ if: matrix.python-version == '3.12'
63
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
64
+ with:
65
+ name: coverage
66
+ path: coverage.xml
67
+
68
+ build:
69
+ name: Build distribution
70
+ needs: test
71
+ runs-on: ubuntu-latest
72
+ timeout-minutes: 10
73
+ steps:
74
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
75
+ - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
76
+ with:
77
+ python-version: "3.12"
78
+ - run: |
79
+ python -m pip install --upgrade pip build
80
+ python -m build
81
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
82
+ with:
83
+ name: dist
84
+ path: dist/
@@ -0,0 +1,48 @@
1
+ name: Pages
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: read
10
+ pages: write
11
+ id-token: write
12
+
13
+ # Actions are pinned to immutable commit SHAs per GitHub's security
14
+ # hardening guidance. Comments retain the human-readable upstream
15
+ # version so Dependabot updates stay reviewable.
16
+
17
+ concurrency:
18
+ group: pages
19
+ cancel-in-progress: true
20
+
21
+ jobs:
22
+ build:
23
+ name: Build Pages artifact
24
+ runs-on: ubuntu-latest
25
+ timeout-minutes: 10
26
+ steps:
27
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
28
+
29
+ - name: Configure GitHub Pages
30
+ uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0
31
+
32
+ - name: Upload static site
33
+ uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
34
+ with:
35
+ path: docs/site
36
+
37
+ deploy:
38
+ name: Deploy Pages site
39
+ needs: build
40
+ runs-on: ubuntu-latest
41
+ timeout-minutes: 10
42
+ environment:
43
+ name: github-pages
44
+ url: ${{ steps.deployment.outputs.page_url }}
45
+ steps:
46
+ - name: Deploy to GitHub Pages
47
+ id: deployment
48
+ uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0
@@ -0,0 +1,162 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*.*.*"
7
+
8
+ permissions:
9
+ contents: write
10
+ packages: write
11
+ id-token: write
12
+
13
+ # Actions are pinned to immutable commit SHAs per GitHub's security
14
+ # hardening guidance. Comments retain the human-readable upstream
15
+ # version so Dependabot updates stay reviewable.
16
+
17
+ jobs:
18
+ build:
19
+ name: Build distributions
20
+ runs-on: ubuntu-latest
21
+ timeout-minutes: 10
22
+ steps:
23
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
24
+
25
+ - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
26
+ with:
27
+ python-version: "3.12"
28
+
29
+ - name: Install build tooling
30
+ run: |
31
+ python -m pip install --upgrade pip build cyclonedx-bom
32
+
33
+ - name: Build wheel and sdist
34
+ run: python -m build
35
+
36
+ - name: Generate CycloneDX SBOM
37
+ run: |
38
+ python -m pip install -e .
39
+ cyclonedx-py environment --output-format json --output-file dist/sbom.cdx.json
40
+
41
+ - name: Upload distribution artifacts
42
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
43
+ with:
44
+ name: dist
45
+ path: dist/
46
+
47
+ publish-pypi:
48
+ name: Publish to PyPI
49
+ needs: build
50
+ runs-on: ubuntu-latest
51
+ timeout-minutes: 10
52
+ environment:
53
+ name: pypi
54
+ url: https://pypi.org/p/docsmoke
55
+ steps:
56
+ - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
57
+ with:
58
+ name: dist
59
+ path: dist/
60
+
61
+ - name: Keep only wheels and sdists for PyPI upload
62
+ run: find dist/ -type f ! -name "*.whl" ! -name "*.tar.gz" -delete
63
+
64
+ - name: Publish via Trusted Publishing
65
+ uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # release/v1
66
+ with:
67
+ packages-dir: dist/
68
+ skip-existing: true
69
+ attestations: true
70
+
71
+ publish-ghcr:
72
+ name: Publish container to GHCR
73
+ needs: build
74
+ runs-on: ubuntu-latest
75
+ timeout-minutes: 30
76
+ permissions:
77
+ contents: read
78
+ packages: write
79
+ steps:
80
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
81
+
82
+ - name: Log in to GHCR
83
+ uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
84
+ with:
85
+ registry: ghcr.io
86
+ username: ${{ github.actor }}
87
+ password: ${{ github.token }}
88
+
89
+ - name: Extract container metadata
90
+ id: meta
91
+ uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
92
+ with:
93
+ images: ghcr.io/${{ github.repository }}
94
+ tags: |
95
+ type=semver,pattern={{version}}
96
+ type=semver,pattern={{major}}.{{minor}}
97
+ type=semver,pattern={{major}}
98
+ type=raw,value=latest
99
+
100
+ - name: Build and push container image
101
+ uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
102
+ with:
103
+ context: .
104
+ file: ./Dockerfile
105
+ push: true
106
+ provenance: false
107
+ tags: ${{ steps.meta.outputs.tags }}
108
+ labels: ${{ steps.meta.outputs.labels }}
109
+
110
+ sign-and-release:
111
+ name: Sign artifacts and create GitHub Release
112
+ needs: build
113
+ runs-on: ubuntu-latest
114
+ timeout-minutes: 10
115
+ steps:
116
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
117
+
118
+ - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
119
+ with:
120
+ name: dist
121
+ path: dist/
122
+
123
+ - name: Sign distributions with sigstore
124
+ uses: sigstore/gh-action-sigstore-python@04cffa1d795717b140764e8b640de88853c92acc # v3.3.0
125
+ with:
126
+ inputs: |
127
+ ./dist/*.whl
128
+ ./dist/*.tar.gz
129
+
130
+ - name: Create or update GitHub Release
131
+ env:
132
+ GH_TOKEN: ${{ github.token }}
133
+ TAG: ${{ github.ref_name }}
134
+ run: |
135
+ set -euo pipefail
136
+ for attempt in 1 2 3; do
137
+ if gh release view "$TAG" >/dev/null 2>&1; then
138
+ gh release upload "$TAG" ./dist/* --clobber && exit 0
139
+ else
140
+ gh release create "$TAG" \
141
+ --title "$TAG" \
142
+ --notes "See CHANGELOG.md for details." \
143
+ ./dist/* && exit 0
144
+ fi
145
+
146
+ if [[ "$attempt" -lt 3 ]]; then
147
+ sleep "$((attempt * 10))"
148
+ fi
149
+ done
150
+
151
+ exit 1
152
+
153
+ - name: Move GitHub Action major tag
154
+ env:
155
+ TAG: ${{ github.ref_name }}
156
+ run: |
157
+ set -euo pipefail
158
+ major="${TAG%%.*}"
159
+ git config user.name "github-actions[bot]"
160
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
161
+ git tag -fa "$major" -m "Update $major to $TAG" "$GITHUB_SHA"
162
+ git push origin "refs/tags/$major" --force
@@ -0,0 +1,13 @@
1
+ .coverage
2
+ .DS_Store
3
+ .mypy_cache/
4
+ .pytest_cache/
5
+ .ruff_cache/
6
+ .venv/
7
+ build/
8
+ coverage.xml
9
+ dist/
10
+ htmlcov/
11
+ __pycache__/
12
+ *.egg-info/
13
+ *.py[cod]
@@ -0,0 +1,42 @@
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v6.0.0
4
+ hooks:
5
+ - id: check-added-large-files
6
+ - id: check-merge-conflict
7
+ - id: check-toml
8
+ - id: check-yaml
9
+ - id: end-of-file-fixer
10
+ - id: trailing-whitespace
11
+
12
+ - repo: https://github.com/astral-sh/ruff-pre-commit
13
+ rev: v0.15.11
14
+ hooks:
15
+ - id: ruff
16
+ args: [--fix]
17
+ - id: ruff-format
18
+
19
+ - repo: https://github.com/pre-commit/mirrors-mypy
20
+ rev: v1.20.1
21
+ hooks:
22
+ - id: mypy
23
+ args: ["--config-file=pyproject.toml"]
24
+ additional_dependencies:
25
+ - rich>=13.7
26
+ - tomli>=2.0
27
+ - typer>=0.12
28
+ - typing-extensions>=4.10
29
+ files: ^src/
30
+
31
+ - repo: https://github.com/PyCQA/bandit
32
+ rev: 1.9.4
33
+ hooks:
34
+ - id: bandit
35
+ args: ["-c", "pyproject.toml", "-q"]
36
+ additional_dependencies: ["bandit[toml]"]
37
+ files: ^src/
38
+
39
+ - repo: https://github.com/gitleaks/gitleaks
40
+ rev: v8.30.1
41
+ hooks:
42
+ - id: gitleaks
@@ -0,0 +1,28 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on Keep a Changelog and this project adheres to Semantic
6
+ Versioning.
7
+
8
+ ## [Unreleased]
9
+
10
+ Nothing yet.
11
+
12
+ ## [1.0.0] - 2026-04-21
13
+
14
+ - Initial public release of `docsmoke`
15
+ - Markdown snippet discovery with explicit `docsmoke` directives
16
+ - Built-in shell and Python executors
17
+ - Per-snippet timeouts, expectations, environment variables, working
18
+ directories, shell overrides, and skips
19
+ - Console, JSON, and Markdown reporting
20
+ - Clean user-facing errors for missing paths, invalid regex expectations, and
21
+ invalid snippet working directories
22
+ - CommonMark-aware fenced-code discovery for nested Markdown examples and tilde
23
+ fences
24
+ - Typed Python package with strict linting, mypy, Bandit, pre-commit, and 100%
25
+ line and branch coverage
26
+ - GitHub Action, CI workflow, release automation, GHCR container publishing,
27
+ Pages deployment, support docs, and repository-governance files
28
+ - Apache 2.0 licensing aligned with the companion `surface-audit` project
@@ -0,0 +1,45 @@
1
+ # Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We are committed to making participation in the `docsmoke` community a
6
+ harassment-free experience for everyone, regardless of age, body size,
7
+ disability, ethnicity, gender identity and expression, level of experience,
8
+ education, socio-economic status, nationality, personal appearance, race,
9
+ religion, or sexual identity and orientation.
10
+
11
+ ## Our Standards
12
+
13
+ Examples of behavior that contributes to a positive environment include:
14
+
15
+ - Demonstrating empathy and kindness toward other people
16
+ - Giving and gracefully accepting constructive feedback
17
+ - Focusing on what is best for the community
18
+ - Showing respect for differing opinions, viewpoints, and experiences
19
+
20
+ Examples of unacceptable behavior include:
21
+
22
+ - The use of sexualized language or imagery, and sexual attention or advances
23
+ - Trolling, insulting or derogatory comments, and personal or political attacks
24
+ - Public or private harassment
25
+ - Publishing others' private information without explicit permission
26
+
27
+ ## Enforcement Responsibilities
28
+
29
+ Project maintainers are responsible for clarifying and enforcing our standards
30
+ of acceptable behavior and will take appropriate and fair corrective action in
31
+ response to any behavior that they deem inappropriate, threatening, offensive,
32
+ or harmful.
33
+
34
+ ## Scope
35
+
36
+ This Code of Conduct applies within all community spaces and when an individual
37
+ is officially representing the project in public spaces.
38
+
39
+ ## Enforcement
40
+
41
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
42
+ reported to dev.ugurkontel@gmail.com.
43
+
44
+ This Code of Conduct is adapted from the Contributor Covenant, version 2.1:
45
+ https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
@@ -0,0 +1,43 @@
1
+ # Contributing to docsmoke
2
+
3
+ Thanks for considering a contribution.
4
+
5
+ ## Development setup
6
+
7
+ ```bash
8
+ git clone <your-fork-or-repo-url>
9
+ cd docsmoke
10
+ make install
11
+ make all
12
+ ```
13
+
14
+ ## Pull requests
15
+
16
+ 1. Open an issue or discussion for substantial changes.
17
+ 2. Keep changes focused and well-tested.
18
+ 3. Update docs for user-facing behavior changes.
19
+ 4. Add or update tests for code changes.
20
+ 5. Keep commit messages intentional and release-note friendly.
21
+
22
+ ## Tooling
23
+
24
+ - `ruff` for linting and formatting
25
+ - `mypy --strict` for type checking
26
+ - `pytest` for tests
27
+ - `pre-commit` for local checks
28
+
29
+ ## Branching and releases
30
+
31
+ - Default branch: `main`
32
+ - Feature branches: `feat/<slug>` or `fix/<slug>`
33
+ - Release tags: `vMAJOR.MINOR.PATCH`
34
+ - Moving GitHub Action tags: `vMAJOR`, for example `v1`
35
+ - Changelog entries belong under `[Unreleased]` until release day
36
+ - Repository settings are tracked in [docs/REPOSITORY.md](docs/REPOSITORY.md)
37
+
38
+ ## Good first contributions
39
+
40
+ - Add new snippet fixtures for real-world docs layouts
41
+ - Improve renderer output
42
+ - Add executor support for another runtime
43
+ - Tighten docs around CI and onboarding workflows
@@ -0,0 +1,30 @@
1
+ # syntax=docker/dockerfile:1.7
2
+
3
+ FROM python:3.12.7-slim AS builder
4
+
5
+ ENV PIP_DISABLE_PIP_VERSION_CHECK=1 \
6
+ PIP_NO_CACHE_DIR=1 \
7
+ PYTHONDONTWRITEBYTECODE=1
8
+
9
+ WORKDIR /build
10
+ RUN pip install --upgrade pip build
11
+
12
+ COPY pyproject.toml README.md LICENSE NOTICE ./
13
+ COPY src ./src
14
+ RUN python -m build --wheel --outdir /dist
15
+
16
+ FROM python:3.12.7-slim AS runtime
17
+
18
+ ENV PYTHONDONTWRITEBYTECODE=1 \
19
+ PYTHONUNBUFFERED=1
20
+
21
+ RUN useradd --create-home --uid 10001 app
22
+
23
+ COPY --from=builder /dist/*.whl /tmp/
24
+ RUN pip install /tmp/*.whl && rm /tmp/*.whl
25
+
26
+ USER app
27
+ WORKDIR /home/app
28
+
29
+ ENTRYPOINT ["docsmoke"]
30
+ CMD ["--help"]