Skip to content

Commit d1a87d6

Browse files
committed
Add schema publishing PoC
1 parent 852e54b commit d1a87d6

20 files changed

+464
-45
lines changed

.github/workflows/test-schema.yaml renamed to .github/workflows/publish-owasp-schema.yaml

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ on:
1616

1717
permissions:
1818
contents: read
19+
id-token: write
1920

2021
concurrency:
2122
cancel-in-progress: true
@@ -104,7 +105,7 @@ jobs:
104105
type=registry,ref=owasp/nest:test-schema-cache
105106
cache-to: |
106107
type=gha,compression=zstd
107-
context: schema
108+
context: .
108109
file: schema/docker/Dockerfile.test
109110
load: true
110111
platforms: linux/amd64
@@ -113,3 +114,75 @@ jobs:
113114
- name: Run schema tests
114115
run: |
115116
docker run --rm owasp/nest:test-schema-latest pytest
117+
118+
publish-schema-package:
119+
name: Publish to PyPI
120+
needs:
121+
- run-schema-tests
122+
runs-on: ubuntu-latest
123+
if: github.ref == 'refs/heads/main'
124+
steps:
125+
- name: Check out repository
126+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
127+
with:
128+
token: ${{ secrets.GITHUB_TOKEN }}
129+
130+
- name: Set up Python
131+
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
132+
with:
133+
python-version: '3.13'
134+
135+
- name: Install Poetry
136+
run: pipx install poetry
137+
138+
- name: Install dependencies
139+
run: |
140+
cd schema
141+
poetry install
142+
143+
- name: Configure Git
144+
run: |
145+
git config --local user.email "[email protected]"
146+
git config --local user.name "GitHub Action"
147+
148+
- name: Bump version
149+
run: |
150+
cd schema
151+
poetry run bump2version patch --commit --tag --allow-dirty
152+
env:
153+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
154+
155+
- name: Push changes
156+
run: |
157+
git push
158+
git push --tags
159+
env:
160+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
161+
162+
- name: Build with new version
163+
run: |
164+
cd schema
165+
poetry build
166+
167+
- name: Publish to PyPI
168+
uses: pypa/gh-action-pypi-publish@release/v1
169+
with:
170+
skip-existing: true
171+
172+
- name: Create GitHub Release
173+
uses: actions/create-release@v1
174+
env:
175+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
176+
with:
177+
tag_name: ${{ github.ref_name }}
178+
release_name: Release ${{ github.ref_name }}
179+
body: |
180+
Automated release for OWASP Schema package.
181+
182+
Changes in this release:
183+
- Updated schema files
184+
- Automated build and publish
185+
186+
Package: https://pypi.org/project/owasp-schema/
187+
draft: false
188+
prerelease: false

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,6 @@ frontend/yarn-debug.log*
3838
frontend/yarn-error.log*
3939
logs
4040
node_modules/
41-
schema/.venv
41+
schema/.venv/
42+
schema/dist/
4243
TODO

docs/scripts/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""Scripts for documentation generation."""

docs/scripts/generate_schema_docs.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
1-
from pathlib import Path
1+
"""Generate schema documentation from JSON schema files."""
2+
3+
# ruff: noqa: S603 https://docs.astral.sh/ruff/rules/subprocess-without-shell-equals-true/
4+
# ruff: noqa: S607 https://docs.astral.sh/ruff/rules/start-process-with-partial-path/
5+
26
import subprocess
7+
from pathlib import Path
38

49

510
def generate_schema_docs():
6-
INPUT_DIR = Path("./schema")
7-
OUTPUT_DIR = Path("./docs/schema")
11+
"""Generate documentation from JSON schema files."""
12+
input_dir = Path("./schema")
13+
output_dir = Path("./docs/schema")
814

9-
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
15+
output_dir.mkdir(parents=True, exist_ok=True)
1016

11-
for schema_file in INPUT_DIR.iterdir():
17+
for schema_file in input_dir.iterdir():
1218
if schema_file.suffix == ".json" and schema_file.name != "common.json":
1319
base_name = schema_file.stem
14-
output_file = OUTPUT_DIR / f"{base_name}.md"
15-
16-
print(f"Processing {schema_file} -> {output_file}")
20+
output_file = output_dir / f"{base_name}.md"
1721

1822
# Generate the schema documentation
1923
subprocess.run(

pyproject.toml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
[tool.poetry]
2+
name = "owasp-schema"
3+
version = "0.1.0"
4+
description = "A collection of OWASP schemas"
5+
authors = ["Arkadii Yakovets <[email protected]>"]
6+
license = "MIT"
7+
readme = "README.md"
8+
homepage = "https://github.com/owasp/nest/schema"
9+
repository = "https://github.com/owasp/nest/schema"
10+
keywords = ["owasp", "schema", "json-schema"]
11+
classifiers = [
12+
"Development Status :: 4 - Beta",
13+
"Intended Audience :: Developers",
14+
"License :: OSI Approved :: MIT License",
15+
"Programming Language :: Python :: 3",
16+
"Programming Language :: Python :: 3.13",
17+
"Topic :: Software Development :: Libraries :: Python Modules",
18+
]
19+
packages = [{ include = "owasp_schema", from = "src" }]
20+
21+
[tool.poetry.dependencies]
22+
jsonschema = "^4.23.0"
23+
pytest = "^8.3.4"
24+
python = "^3.13"
25+
pyyaml = "^6.0.2"
26+
validators = "^0.35.0"
27+
28+
[tool.poetry.group.dev.dependencies]
29+
bump2version = "^1.0.1"
30+
pytest = "^8.3.4"
31+
32+
[tool.poetry.build]
33+
generate-setup-file = false
34+
35+
[tool.ruff]
36+
line-length = 99
37+
target-version = "py313"
38+
39+
[tool.ruff.lint]
40+
extend-select = ["I"]
41+
ignore = [
42+
"ANN",
43+
"D103",
44+
]
45+
select = ["ALL"]
46+
47+
[tool.ruff.lint.per-file-ignores]
48+
"**/__init__.py" = ["D104"]
49+
"**/*.py" = ["S101"]
50+
51+
[build-system]
52+
requires = ["poetry-core"]
53+
build-backend = "poetry.core.masonry.api"

schema/.bumpversion.cfg

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[bumpversion]
2+
current_version = 0.1.0
3+
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)
4+
serialize = {major}.{minor}.{patch}
5+
files =
6+
pyproject.toml
7+
src/owasp_schema/__init__.py
8+
9+
[bumpversion:file:pyproject.toml]
10+
search = version = "{current_version}"
11+
replace = version = "{new_version}"
12+
13+
[bumpversion:file:src/owasp_schema/__init__.py]
14+
search = __version__ = "{current_version}"
15+
replace = __version__ = "{new_version}"

schema/MANIFEST.in

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
include *.json
2+
include *.py
3+
include *.md
4+
include *.cfg
5+
include README.md
6+
include LICENSE
7+
include src/owasp_schema/*.json
8+
recursive-exclude tests *
9+
recursive-exclude docker *
10+
recursive-exclude utils *
11+
recursive-exclude .venv *
12+
recursive-exclude dist *
13+
recursive-exclude build *
14+
recursive-exclude __pycache__ *
15+
recursive-exclude .pytest_cache *
16+
recursive-exclude .ruff_cache *
17+
exclude *.lock

schema/Makefile

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,43 @@
1+
build-owasp-schema-package:
2+
cd schema && poetry build
3+
4+
bump-owasp-schema-major:
5+
cd schema && poetry run bump2version major --allow-dirty
6+
7+
bump-owasp-schema-minor:
8+
cd schema && poetry run bump2version minor --allow-dirty
9+
10+
bump-owasp-schema-patch:
11+
cd schema && poetry run bump2version patch --allow-dirty
12+
13+
bump-owasp-schema-major-commit:
14+
cd schema && poetry run bump2version major --commit --tag --allow-dirty
15+
16+
bump-owasp-schema-minor-commit:
17+
cd schema && poetry run bump2version minor --commit --tag --allow-dirty
18+
19+
bump-owasp-schema-patch-commit:
20+
cd schema && poetry run bump2version patch --commit --tag --allow-dirty
21+
22+
clean-package:
23+
cd schema && rm -rf dist/ build/ *.egg-info/
24+
125
clean-schema-dependencies:
226
@rm -rf schema/.venv
327

28+
install-owasp-schema-package:
29+
cd schema && poetry install
30+
31+
publish-package:
32+
cd schema && poetry publish
33+
434
test-schema:
535
@DOCKER_BUILDKIT=1 docker build \
636
--cache-from nest-test-schema \
7-
-f schema/docker/Dockerfile.test schema \
37+
-f schema/docker/Dockerfile.test . \
838
-t nest-test-schema
939
@docker run --rm nest-test-schema pytest
1040

41+
1142
update-schema-dependencies:
1243
cd schema && poetry update

schema/README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# OWASP Schema
2+
3+
A Python package providing JSON schemas for OWASP projects.
4+
5+
## Installation
6+
7+
```bash
8+
pip install owasp-schema
9+
```
10+
11+
## Usage
12+
13+
```python
14+
from owasp_schema import get_schema, list_schemas, chapter_schema
15+
16+
# List all available schemas
17+
print(list_schemas())
18+
# Output: ['chapter', 'committee', 'project']
19+
20+
# Get a specific schema
21+
chapter_schema = get_schema("chapter")
22+
23+
# Or use the pre-loaded schemas
24+
print(chapter_schema["title"])
25+
```
26+
27+
## Available Schemas
28+
29+
- `chapter`: Schema for OWASP chapters
30+
- `committee`: Schema for OWASP committees
31+
- `project`: Schema for OWASP projects
32+
33+
## Development
34+
35+
This package is automatically published to PyPI when schema files change in the main branch using OIDC authentication.
36+
37+
## License
38+
39+
MIT License - see LICENSE file for details.

schema/docker/Dockerfile.test

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ RUN --mount=type=cache,target=${PIP_CACHE_DIR} \
2727
WORKDIR /home/owasp
2828
USER owasp
2929

30-
COPY --chmod=444 --chown=root:root poetry.lock pyproject.toml ./
30+
COPY --chmod=444 --chown=root:root schema/poetry.lock schema/pyproject.toml ./
3131
RUN --mount=type=cache,target=${POETRY_CACHE_DIR},uid=${OWASP_UID},gid=${OWASP_GID} \
3232
poetry install --no-root
3333

34-
COPY *.json ./
35-
COPY tests tests
36-
COPY utils utils
34+
COPY schema/src/owasp_schema owasp_schema
35+
COPY schema/*.json owasp_schema/
36+
COPY schema/tests tests
3737

3838
FROM python:3.13.5-alpine
3939

0 commit comments

Comments
 (0)