ossplate 0.1.0
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.
- package/README.md +7 -0
- package/bin/darwin-arm64/ossplate +0 -0
- package/bin/darwin-x64/ossplate +3 -0
- package/bin/linux-x64/ossplate +3 -0
- package/bin/ossplate.js +5 -0
- package/bin/win32-x64/ossplate.exe +3 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +56 -0
- package/package.json +43 -0
- package/scaffold/.github/workflows/ci.yml +76 -0
- package/scaffold/.github/workflows/publish-npm.yml +45 -0
- package/scaffold/.github/workflows/publish.yml +97 -0
- package/scaffold/.gitignore +9 -0
- package/scaffold/CONTRIBUTING.md +30 -0
- package/scaffold/LICENSE +9 -0
- package/scaffold/README.md +73 -0
- package/scaffold/core-rs/Cargo.lock +338 -0
- package/scaffold/core-rs/Cargo.toml +28 -0
- package/scaffold/core-rs/src/main.rs +1609 -0
- package/scaffold/docs/README.md +21 -0
- package/scaffold/docs/customizing-the-template.md +144 -0
- package/scaffold/docs/phase-1-contract.md +52 -0
- package/scaffold/docs/testing.md +71 -0
- package/scaffold/docs/upgrade-plan.md +251 -0
- package/scaffold/ossplate.toml +15 -0
- package/scaffold/scripts/verify.sh +36 -0
- package/scaffold/wrapper-js/README.md +7 -0
- package/scaffold/wrapper-js/bin/darwin-arm64/ossplate +0 -0
- package/scaffold/wrapper-js/bin/darwin-x64/ossplate +3 -0
- package/scaffold/wrapper-js/bin/linux-x64/ossplate +3 -0
- package/scaffold/wrapper-js/bin/ossplate.js +5 -0
- package/scaffold/wrapper-js/bin/win32-x64/ossplate.exe +3 -0
- package/scaffold/wrapper-js/package-lock.json +51 -0
- package/scaffold/wrapper-js/package.json +43 -0
- package/scaffold/wrapper-js/src/index.ts +69 -0
- package/scaffold/wrapper-js/tsconfig.json +14 -0
- package/scaffold/wrapper-py/README.md +7 -0
- package/scaffold/wrapper-py/hatch_build.py +16 -0
- package/scaffold/wrapper-py/pyproject.toml +37 -0
- package/scaffold/wrapper-py/src/ossplate/__init__.py +3 -0
- package/scaffold/wrapper-py/src/ossplate/bin/darwin-arm64/ossplate +0 -0
- package/scaffold/wrapper-py/src/ossplate/bin/darwin-x64/ossplate +3 -0
- package/scaffold/wrapper-py/src/ossplate/bin/linux-x64/ossplate +3 -0
- package/scaffold/wrapper-py/src/ossplate/bin/win32-x64/ossplate.exe +3 -0
- package/scaffold/wrapper-py/src/ossplate/cli.py +55 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Documentation
|
|
2
|
+
|
|
3
|
+
This docs area explains how to use `ossplate` as a real tool for validating, synchronizing, and now creating a multi-registry scaffold.
|
|
4
|
+
|
|
5
|
+
## Start Here
|
|
6
|
+
|
|
7
|
+
- [Customizing The Template](./customizing-the-template.md)
|
|
8
|
+
- [Testing Guide](./testing.md)
|
|
9
|
+
- [Phase 1 Contract](./phase-1-contract.md)
|
|
10
|
+
- [Upgrade Plan](./upgrade-plan.md)
|
|
11
|
+
- `ossplate validate` checks owned metadata drift
|
|
12
|
+
- `ossplate sync --check` verifies the repo is already synchronized
|
|
13
|
+
- `ossplate create <target>` scaffolds a clean target directory and can apply identity overrides from flags
|
|
14
|
+
- `ossplate init --path <dir>` hydrates an existing directory in place and can apply identity overrides from flags
|
|
15
|
+
|
|
16
|
+
## What These Docs Cover
|
|
17
|
+
|
|
18
|
+
- the canonical config and command surface
|
|
19
|
+
- the required rename and customization surface before first release
|
|
20
|
+
- the layered testing and packaging workflow
|
|
21
|
+
- the phased plan for turning this tool into a broader scaffold product
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Customizing The Template
|
|
2
|
+
|
|
3
|
+
Use this checklist after creating or cloning a scaffold managed by `ossplate`. The goal is to replace inherited identity deliberately and then use the tool to keep owned metadata in sync.
|
|
4
|
+
|
|
5
|
+
## Canonical Source Of Truth
|
|
6
|
+
|
|
7
|
+
`ossplate.toml` is the canonical source of truth for the shared project identity.
|
|
8
|
+
|
|
9
|
+
It currently owns:
|
|
10
|
+
|
|
11
|
+
- project name
|
|
12
|
+
- project description
|
|
13
|
+
- repository URL
|
|
14
|
+
- license
|
|
15
|
+
- author name/email
|
|
16
|
+
- Rust crate name
|
|
17
|
+
- npm package name
|
|
18
|
+
- Python package name
|
|
19
|
+
- CLI command name
|
|
20
|
+
|
|
21
|
+
`ossplate validate` checks that the owned surfaces match this config.
|
|
22
|
+
|
|
23
|
+
`ossplate sync` rewrites the owned surfaces back into alignment.
|
|
24
|
+
|
|
25
|
+
## Validation Policy
|
|
26
|
+
|
|
27
|
+
- Placeholder identities are allowed only when the repository is discussing the template itself.
|
|
28
|
+
- Placeholder identities are not allowed in shipping metadata or package-facing docs for an adopted project.
|
|
29
|
+
- Command and package naming must be chosen intentionally before release.
|
|
30
|
+
- Author, repository, and license fields must be set explicitly rather than inherited accidentally.
|
|
31
|
+
|
|
32
|
+
The current validator follows this policy through the Rust core rather than a standalone JS rule engine.
|
|
33
|
+
|
|
34
|
+
## Required Renames
|
|
35
|
+
|
|
36
|
+
Replace these defaults before reuse:
|
|
37
|
+
|
|
38
|
+
| Surface | Current placeholder | Where it lives |
|
|
39
|
+
| --- | --- | --- |
|
|
40
|
+
| Rust crate name | `ossplate` | `core-rs/Cargo.toml` |
|
|
41
|
+
| npm package name | `ossplate` | `wrapper-js/package.json` |
|
|
42
|
+
| PyPI package name | `ossplate` | `wrapper-py/pyproject.toml` |
|
|
43
|
+
| CLI command | `ossplate` | `ossplate.toml`, `wrapper-js/package.json`, `wrapper-py/pyproject.toml` |
|
|
44
|
+
| Repository URL | `https://github.com/stefdevscore/ossplate` | Rust, npm, Python metadata |
|
|
45
|
+
| Author/email | `Stef <stefdevscore@github.com>` / `stefdevscore@github.com` | Rust, npm, Python metadata |
|
|
46
|
+
| Package-facing template branding | `OSS template`, `template` identity in wrapper docs | `wrapper-js/README.md`, `wrapper-py/README.md` |
|
|
47
|
+
|
|
48
|
+
## Files To Review
|
|
49
|
+
|
|
50
|
+
- `README.md`
|
|
51
|
+
- `ossplate.toml`
|
|
52
|
+
- `core-rs/Cargo.toml`
|
|
53
|
+
- `wrapper-js/package.json`
|
|
54
|
+
- `wrapper-js/README.md`
|
|
55
|
+
- `wrapper-py/pyproject.toml`
|
|
56
|
+
- `wrapper-py/README.md`
|
|
57
|
+
- `.github/workflows/*.yml`
|
|
58
|
+
|
|
59
|
+
## What `ossplate validate` Enforces
|
|
60
|
+
|
|
61
|
+
The tool reports:
|
|
62
|
+
|
|
63
|
+
- drift between `ossplate.toml` and the owned manifest fields
|
|
64
|
+
- drift between `ossplate.toml` and wrapper package README identity
|
|
65
|
+
- missing or malformed owned metadata in Cargo, npm, or Python surfaces
|
|
66
|
+
|
|
67
|
+
The tool does not currently rewrite or own:
|
|
68
|
+
|
|
69
|
+
- CI workflow logic
|
|
70
|
+
- publish workflow auth logic
|
|
71
|
+
- the root README body beyond the marked identity block
|
|
72
|
+
- arbitrary docs prose
|
|
73
|
+
|
|
74
|
+
The root `README.md` now has a bounded identity section managed by `ossplate sync`. Content outside that marker block remains intentionally manual.
|
|
75
|
+
|
|
76
|
+
The workflow files now expose a similarly bounded identity surface:
|
|
77
|
+
|
|
78
|
+
- `.github/workflows/ci.yml`
|
|
79
|
+
- `.github/workflows/publish.yml`
|
|
80
|
+
- `.github/workflows/publish-npm.yml`
|
|
81
|
+
|
|
82
|
+
`sync` owns only the display name between `ossplate:workflow-name` markers. Trigger logic, jobs, auth, and shell steps remain manual.
|
|
83
|
+
|
|
84
|
+
## First-Run Sequence After Cloning
|
|
85
|
+
|
|
86
|
+
1. Either update `ossplate.toml` directly or use `create` / `init` with identity flags.
|
|
87
|
+
2. Run `cargo run --manifest-path core-rs/Cargo.toml -- sync`.
|
|
88
|
+
3. Run `cargo run --manifest-path core-rs/Cargo.toml -- validate`.
|
|
89
|
+
4. Run the layered verification flow from [Testing Guide](./testing.md).
|
|
90
|
+
5. Only then expand product code or publish configuration.
|
|
91
|
+
|
|
92
|
+
## Create Workflow
|
|
93
|
+
|
|
94
|
+
To scaffold a fresh target from the current template tree:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
cargo run --manifest-path core-rs/Cargo.toml -- create ../my-new-project \
|
|
98
|
+
--name "My Project" \
|
|
99
|
+
--repository "https://github.com/acme/my-project" \
|
|
100
|
+
--author-name "Acme OSS" \
|
|
101
|
+
--author-email "oss@acme.dev" \
|
|
102
|
+
--rust-crate "my-project-core" \
|
|
103
|
+
--npm-package "@acme/my-project" \
|
|
104
|
+
--python-package "my-project-py" \
|
|
105
|
+
--command "my-project"
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
That copies the curated scaffold payload into the target directory, applies any identity overrides to `ossplate.toml`, then runs `sync` on the new target.
|
|
109
|
+
|
|
110
|
+
The packaged scaffold intentionally excludes wrapper test suites and maintainer-only validation scripts. Generated projects get the delivery baseline and operator docs, not the source repo's internal test harness.
|
|
111
|
+
|
|
112
|
+
## Init Workflow
|
|
113
|
+
|
|
114
|
+
To hydrate an existing directory in place:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
cargo run --manifest-path core-rs/Cargo.toml -- init \
|
|
118
|
+
--path ../existing-project \
|
|
119
|
+
--name "Existing Project" \
|
|
120
|
+
--command "existing-project"
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
`init` ensures the expected scaffold layout exists, copies any missing scaffold files, applies any requested identity overrides, and then runs `sync` so owned metadata matches `ossplate.toml`.
|
|
124
|
+
|
|
125
|
+
## Supported Identity Flags
|
|
126
|
+
|
|
127
|
+
- `--name`
|
|
128
|
+
- `--description`
|
|
129
|
+
- `--repository`
|
|
130
|
+
- `--license`
|
|
131
|
+
- `--author-name`
|
|
132
|
+
- `--author-email`
|
|
133
|
+
- `--rust-crate`
|
|
134
|
+
- `--npm-package`
|
|
135
|
+
- `--python-package`
|
|
136
|
+
- `--command`
|
|
137
|
+
|
|
138
|
+
## Why This Exists
|
|
139
|
+
|
|
140
|
+
This tool is trying to optimize for a real delivery baseline:
|
|
141
|
+
|
|
142
|
+
- CI should fail before placeholder identity reaches a release path.
|
|
143
|
+
- package metadata should not be inherited by accident
|
|
144
|
+
- future phases can add richer scaffold creation and maintenance without first cleaning up metadata drift
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Phase 1 Contract
|
|
2
|
+
|
|
3
|
+
Phase 1 establishes a single canonical CLI surface in the Rust core. The JavaScript and Python packages are wrappers that delegate to that binary rather than implementing separate behavior.
|
|
4
|
+
|
|
5
|
+
## Canonical Commands
|
|
6
|
+
|
|
7
|
+
- `version`
|
|
8
|
+
returns JSON with the tool identity and package version
|
|
9
|
+
- `validate [--path <dir>] [--json]`
|
|
10
|
+
returns validation results for owned metadata surfaces
|
|
11
|
+
- `sync [--path <dir>] [--check]`
|
|
12
|
+
rewrites or checks owned metadata surfaces against the canonical project identity
|
|
13
|
+
- `create <target>`
|
|
14
|
+
copies the curated scaffold payload into a clean target directory, applies optional identity overrides, and synchronizes the owned metadata surfaces there
|
|
15
|
+
- `init [--path <dir>]`
|
|
16
|
+
hydrates an existing directory with the expected scaffold layout, applies optional identity overrides, and then synchronizes owned metadata in place
|
|
17
|
+
|
|
18
|
+
Both commands are available from source checkouts and installed wrapper artifacts that include the staged scaffold payload.
|
|
19
|
+
|
|
20
|
+
## Expected Output Shapes
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{"tool":"ossplate","version":"0.1.0"}
|
|
24
|
+
{"ok":true,"issues":[]}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Wrapper Model
|
|
28
|
+
|
|
29
|
+
- Rust is the source of truth for command parsing and output.
|
|
30
|
+
- JavaScript and Python are adapter layers that resolve a packaged binary and forward arguments unchanged.
|
|
31
|
+
- Wrappers preserve stdout, stderr, and exit status from the core binary.
|
|
32
|
+
|
|
33
|
+
## Local Development Override
|
|
34
|
+
|
|
35
|
+
Both wrappers support `OSSPLATE_BINARY` to bypass packaged binary lookup during local development and parity testing.
|
|
36
|
+
|
|
37
|
+
`create` and `init` also honor `OSSPLATE_TEMPLATE_ROOT` when the template source needs to be overridden explicitly.
|
|
38
|
+
|
|
39
|
+
## Packaged Binary Layout
|
|
40
|
+
|
|
41
|
+
Wrappers expect binaries under:
|
|
42
|
+
|
|
43
|
+
```text
|
|
44
|
+
bin/<target>/<executable>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Supported target identifiers are aligned across wrappers:
|
|
48
|
+
|
|
49
|
+
- `darwin-arm64`
|
|
50
|
+
- `darwin-x64`
|
|
51
|
+
- `linux-x64`
|
|
52
|
+
- `win32-x64`
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Testing Guide
|
|
2
|
+
|
|
3
|
+
`ossplate` uses layered verification so the scaffold stays usable as both a source checkout and an installed wrapper distribution.
|
|
4
|
+
|
|
5
|
+
## Default Layers
|
|
6
|
+
|
|
7
|
+
### Smoke
|
|
8
|
+
|
|
9
|
+
- `cargo run --manifest-path core-rs/Cargo.toml -- validate`
|
|
10
|
+
- `cargo run --manifest-path core-rs/Cargo.toml -- sync --check`
|
|
11
|
+
- `cargo run --manifest-path core-rs/Cargo.toml -- create ../tmp-project`
|
|
12
|
+
- `cargo run --manifest-path core-rs/Cargo.toml -- init --path ../tmp-project`
|
|
13
|
+
|
|
14
|
+
### Unit And Integration
|
|
15
|
+
|
|
16
|
+
- `cargo test`
|
|
17
|
+
- `npm test`
|
|
18
|
+
- `PYTHONPATH=src python3 -m unittest discover -s tests -p 'test_*.py'`
|
|
19
|
+
|
|
20
|
+
These suites cover:
|
|
21
|
+
|
|
22
|
+
- Rust command parsing and metadata sync behavior
|
|
23
|
+
- wrapper parity against the Rust core
|
|
24
|
+
- installed npm and wheel artifact smoke checks for `version`, `create`, and `validate`
|
|
25
|
+
|
|
26
|
+
### Packaging
|
|
27
|
+
|
|
28
|
+
- `npm pack --dry-run` in `wrapper-js/`
|
|
29
|
+
- `python -m build --wheel` in `wrapper-py/`
|
|
30
|
+
|
|
31
|
+
JavaScript packaging stages distribution assets through `prepack`.
|
|
32
|
+
|
|
33
|
+
Python packaging stages distribution assets through the Hatch build hook in `wrapper-py/hatch_build.py`.
|
|
34
|
+
|
|
35
|
+
Artifact assertions are part of the required packaging layer:
|
|
36
|
+
|
|
37
|
+
- npm tarball content must include the curated scaffold files from `scaffold-manifest.json`
|
|
38
|
+
- npm tarball content must exclude wrapper test files and repo-only validation scripts
|
|
39
|
+
- Python wheel content must include the curated scaffold files from `scaffold-manifest.json`
|
|
40
|
+
- Python wheel content must exclude wrapper test files and repo-only validation scripts
|
|
41
|
+
|
|
42
|
+
## Recommended Local Order
|
|
43
|
+
|
|
44
|
+
Default path:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
./scripts/verify.sh
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Underlying command order:
|
|
51
|
+
|
|
52
|
+
1. `cargo fmt --check`
|
|
53
|
+
2. `cargo clippy --manifest-path core-rs/Cargo.toml -- -D warnings`
|
|
54
|
+
3. `cargo test`
|
|
55
|
+
4. `cargo run --quiet --manifest-path core-rs/Cargo.toml -- validate --json`
|
|
56
|
+
5. `cargo run --quiet --manifest-path core-rs/Cargo.toml -- sync --check`
|
|
57
|
+
6. `npm test`
|
|
58
|
+
7. `npm pack --dry-run`
|
|
59
|
+
8. `PYTHONPATH=src python3 -m unittest discover -s tests -p 'test_*.py'`
|
|
60
|
+
9. `python -m build --wheel`
|
|
61
|
+
|
|
62
|
+
## CI Expectations
|
|
63
|
+
|
|
64
|
+
CI currently enforces:
|
|
65
|
+
|
|
66
|
+
- template readiness via `validate` and `sync --check`
|
|
67
|
+
- Rust formatting, clippy, and tests
|
|
68
|
+
- JS build, tests, and package dry-run
|
|
69
|
+
- Python tests and wheel build
|
|
70
|
+
|
|
71
|
+
The current artifact tests are the required release-confidence floor. Future phases can add broader platform coverage or slower end-to-end suites without changing the basic layered model.
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# Ossplate Upgrade Plan
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Turn `ossplate` from a minimal multi-registry demo into a production-ready scaffold tool with:
|
|
6
|
+
|
|
7
|
+
- one canonical core program
|
|
8
|
+
- real wrapper parity across Rust, TypeScript/JavaScript, and Python
|
|
9
|
+
- robust CI and publish workflows with explicit auth fallbacks
|
|
10
|
+
- layered testing guidance and enforcement
|
|
11
|
+
- a structure that can scale toward a hexagonal architecture shell
|
|
12
|
+
|
|
13
|
+
The product behavior is now real in the core maintenance and scaffold paths. Remaining work is about hardening, ergonomics, and release scale.
|
|
14
|
+
|
|
15
|
+
## Operating Principles
|
|
16
|
+
|
|
17
|
+
- Keep one source of truth for CLI behavior and output contracts.
|
|
18
|
+
- Prefer thin wrappers over duplicated implementations.
|
|
19
|
+
- Fail early when template placeholders were not replaced.
|
|
20
|
+
- Use OIDC where the registry path is configured and supported, with explicit token fallbacks elsewhere.
|
|
21
|
+
- Require install/build/test/package checks before any publish step.
|
|
22
|
+
- Keep the starter small, but not fake in the critical paths.
|
|
23
|
+
|
|
24
|
+
## Phase 0: Stabilize the Template Baseline
|
|
25
|
+
|
|
26
|
+
Purpose: make the current scaffold safe to evolve and hard to misuse.
|
|
27
|
+
|
|
28
|
+
### P0
|
|
29
|
+
|
|
30
|
+
- Add a release-readiness validator that fails on placeholder metadata.
|
|
31
|
+
- Validate package names, crate name, binary names, repository URLs, author fields, and obvious placeholder strings.
|
|
32
|
+
- Add a root documentation index under `docs/` so implementation docs have a stable home.
|
|
33
|
+
|
|
34
|
+
### P1
|
|
35
|
+
|
|
36
|
+
- Normalize naming conventions across Cargo, npm, and PyPI packages.
|
|
37
|
+
- Define the canonical command name and the expected wrapper naming pattern.
|
|
38
|
+
- Document the template customization surface:
|
|
39
|
+
project name, package ids, repo URL, author, license, binary name, description.
|
|
40
|
+
|
|
41
|
+
### P2
|
|
42
|
+
|
|
43
|
+
- Remove or tighten weak placeholder copy in README files.
|
|
44
|
+
- Add a checklist for creating a new project from the template.
|
|
45
|
+
|
|
46
|
+
### Exit Criteria
|
|
47
|
+
|
|
48
|
+
- A new maintainer can identify every required rename/customization step.
|
|
49
|
+
- CI can fail automatically if placeholder identity leaks into a release path.
|
|
50
|
+
|
|
51
|
+
## Phase 1: Establish the Canonical Core and Wrapper Parity
|
|
52
|
+
|
|
53
|
+
Purpose: stop treating each ecosystem as a separate product stub.
|
|
54
|
+
|
|
55
|
+
### P0
|
|
56
|
+
|
|
57
|
+
- Make the Rust binary the canonical executable implementation.
|
|
58
|
+
- Define a small, stable placeholder command contract:
|
|
59
|
+
`--help`, `version`, `health`, and one example command returning structured JSON.
|
|
60
|
+
- Convert the JavaScript package into a real wrapper around the packaged binary.
|
|
61
|
+
- Convert the Python package into a real wrapper around the packaged binary.
|
|
62
|
+
- Ensure wrappers preserve exit codes, stdout, and stderr from the core binary.
|
|
63
|
+
|
|
64
|
+
### P1
|
|
65
|
+
|
|
66
|
+
- Move `wrapper-js` source to TypeScript and publish built JavaScript artifacts.
|
|
67
|
+
- Add binary resolution logic for supported platforms in both wrappers.
|
|
68
|
+
- Add wrapper tests that assert parity against the core binary output contract.
|
|
69
|
+
|
|
70
|
+
### P2
|
|
71
|
+
|
|
72
|
+
- Add a small shared contract document covering commands, arguments, output, and error behavior.
|
|
73
|
+
- Add support for environment-based binary overrides for local development and debugging.
|
|
74
|
+
|
|
75
|
+
### Exit Criteria
|
|
76
|
+
|
|
77
|
+
- Rust, JS, and Python packages all exercise the same underlying behavior.
|
|
78
|
+
- Wrapper packages no longer maintain separate hand-written CLI logic.
|
|
79
|
+
|
|
80
|
+
## Phase 2: Production-Grade Quality Gates
|
|
81
|
+
|
|
82
|
+
Purpose: make the scaffold trustworthy before publish automation runs.
|
|
83
|
+
|
|
84
|
+
### P0
|
|
85
|
+
|
|
86
|
+
- Expand CI to enforce core quality gates in all three environments.
|
|
87
|
+
- Add Rust checks:
|
|
88
|
+
`cargo fmt --check`, `cargo clippy -- -D warnings`, `cargo test`.
|
|
89
|
+
- Add JS/TS checks:
|
|
90
|
+
install, typecheck, test, package dry-run.
|
|
91
|
+
- Add Python checks:
|
|
92
|
+
environment setup, tests, wheel/sdist build, install-from-built-artifact smoke test.
|
|
93
|
+
- Add a cross-package parity job that verifies wrappers match core contract behavior.
|
|
94
|
+
|
|
95
|
+
### P1
|
|
96
|
+
|
|
97
|
+
- Add artifact-level smoke tests for packaged npm and wheel outputs.
|
|
98
|
+
- Add a matrix strategy where it materially improves confidence for supported platforms.
|
|
99
|
+
- Make CI logs and job names intentionally clear for template adopters.
|
|
100
|
+
|
|
101
|
+
### P2
|
|
102
|
+
|
|
103
|
+
- Add optional local aggregate commands or scripts for running all checks consistently.
|
|
104
|
+
- Add a contributor quickstart for running the same quality gates outside CI.
|
|
105
|
+
|
|
106
|
+
### Exit Criteria
|
|
107
|
+
|
|
108
|
+
- A release candidate must pass formatting, linting, unit tests, packaging, and parity checks.
|
|
109
|
+
- Published artifacts are verified before publish jobs run.
|
|
110
|
+
|
|
111
|
+
## Phase 3: Robust Publishing with OIDC First and Concrete Fallbacks
|
|
112
|
+
|
|
113
|
+
Purpose: keep publishing reliable even when registry auth or registry behavior is imperfect.
|
|
114
|
+
|
|
115
|
+
### P0
|
|
116
|
+
|
|
117
|
+
- Keep publish workflows rerun-safe with published-version detection before attempting release.
|
|
118
|
+
- Use OIDC or trusted publishing where supported and configured.
|
|
119
|
+
- For the current `ossplate` baseline:
|
|
120
|
+
PyPI uses OIDC, Cargo uses OIDC with `CARGO_TOKEN` fallback, and npm uses `NPM_TOKEN`.
|
|
121
|
+
- Add explicit secret-based fallbacks:
|
|
122
|
+
`NPM_TOKEN`, PyPI API token, and `CARGO_REGISTRY_TOKEN`.
|
|
123
|
+
- Make auth mode selection visible in workflow logs.
|
|
124
|
+
- Preserve non-destructive handling of already-published versions.
|
|
125
|
+
|
|
126
|
+
### P1
|
|
127
|
+
|
|
128
|
+
- Document exact registry setup steps for both preferred and fallback auth modes.
|
|
129
|
+
- Add validation that publish jobs fail clearly when neither OIDC nor token auth is configured.
|
|
130
|
+
- Tighten registry-specific behavior:
|
|
131
|
+
npm public access, PyPI trusted publishing expectations, crates.io version detection and retry behavior.
|
|
132
|
+
|
|
133
|
+
### P2
|
|
134
|
+
|
|
135
|
+
- Add optional manual dispatch inputs for dry-run or targeted registry publish flows if they simplify maintenance.
|
|
136
|
+
- Add guidance for organizations that intentionally disable OIDC and standardize on tokens.
|
|
137
|
+
|
|
138
|
+
### Exit Criteria
|
|
139
|
+
|
|
140
|
+
- Publish workflows are understandable, rerunnable, and resilient.
|
|
141
|
+
- Auth failures are explicit and actionable rather than implicit or flaky.
|
|
142
|
+
|
|
143
|
+
## Phase 4: Layered Testing Guidance and Scaffolding
|
|
144
|
+
|
|
145
|
+
Purpose: teach adopters how to scale verification without overcomplicating the starter.
|
|
146
|
+
|
|
147
|
+
### P0
|
|
148
|
+
|
|
149
|
+
- Add docs for the default testing pyramid:
|
|
150
|
+
smoke, unit, integration/parity, and release verification.
|
|
151
|
+
- Define minimum required tests for any project generated from this template.
|
|
152
|
+
- Document how wrapper parity tests fit into the scaffold.
|
|
153
|
+
|
|
154
|
+
### P1
|
|
155
|
+
|
|
156
|
+
- Add optional docs for live end-to-end browser testing with Playwright when a generated project includes a web UI.
|
|
157
|
+
- Clarify that Playwright is not a default requirement for non-UI projects.
|
|
158
|
+
- Add example CI placement for smoke vs slower e2e suites.
|
|
159
|
+
|
|
160
|
+
### P2
|
|
161
|
+
|
|
162
|
+
- Add template examples of failure triage:
|
|
163
|
+
unit regression, packaging regression, publish regression, wrapper parity regression.
|
|
164
|
+
|
|
165
|
+
### Exit Criteria
|
|
166
|
+
|
|
167
|
+
- The testing strategy is clear enough that teams do not improvise incompatible structures from scratch.
|
|
168
|
+
- Optional e2e guidance exists without forcing UI assumptions onto every project.
|
|
169
|
+
|
|
170
|
+
## Phase 5: Architecture Shell and Scaling Docs
|
|
171
|
+
|
|
172
|
+
Purpose: leave room for serious product evolution without bloating the first scaffold cut.
|
|
173
|
+
|
|
174
|
+
### P1
|
|
175
|
+
|
|
176
|
+
- Add architecture docs for a hexagonal baseline:
|
|
177
|
+
domain, application, adapters, and delivery surfaces.
|
|
178
|
+
- Define where product logic belongs and where it should not live.
|
|
179
|
+
- Document wrappers as adapters rather than alternate implementations.
|
|
180
|
+
|
|
181
|
+
### P2
|
|
182
|
+
|
|
183
|
+
- Add an example directory shell that future projects can expand into as complexity grows.
|
|
184
|
+
- Link to the stronger internal reference material that informed this structure.
|
|
185
|
+
- Add ADR guidance if the template grows beyond a small starter.
|
|
186
|
+
|
|
187
|
+
### Exit Criteria
|
|
188
|
+
|
|
189
|
+
- The template can scale into a maintainable project layout without major restructuring.
|
|
190
|
+
- The initial starter remains small and understandable.
|
|
191
|
+
|
|
192
|
+
## Recommended Execution Order
|
|
193
|
+
|
|
194
|
+
1. Phase 0
|
|
195
|
+
2. Phase 1
|
|
196
|
+
3. Phase 2
|
|
197
|
+
4. Phase 3
|
|
198
|
+
5. Phase 4
|
|
199
|
+
6. Phase 5
|
|
200
|
+
|
|
201
|
+
Rationale:
|
|
202
|
+
|
|
203
|
+
- Phase 0 prevents accidental misuse while the template is still changing.
|
|
204
|
+
- Phase 1 fixes the most important structural flaw: duplicated CLI stubs.
|
|
205
|
+
- Phase 2 makes the scaffold trustworthy.
|
|
206
|
+
- Phase 3 hardens release automation after the package surfaces are stable.
|
|
207
|
+
- Phase 4 and Phase 5 improve scale and adoption quality without blocking the core scaffold.
|
|
208
|
+
|
|
209
|
+
## Suggested Near-Term Milestones
|
|
210
|
+
|
|
211
|
+
### Milestone A
|
|
212
|
+
|
|
213
|
+
Complete Phases 0 and 1.
|
|
214
|
+
|
|
215
|
+
Outcome:
|
|
216
|
+
`ossplate` becomes a real scaffold with one canonical core and thin wrappers.
|
|
217
|
+
|
|
218
|
+
### Milestone B
|
|
219
|
+
|
|
220
|
+
Complete Phase 2 and the P0 items in Phase 3.
|
|
221
|
+
|
|
222
|
+
Outcome:
|
|
223
|
+
the scaffold becomes release-grade with meaningful quality gates and robust publish behavior.
|
|
224
|
+
|
|
225
|
+
### Milestone C
|
|
226
|
+
|
|
227
|
+
Complete Phases 4 and 5.
|
|
228
|
+
|
|
229
|
+
Outcome:
|
|
230
|
+
the scaffold becomes easier to adopt, extend, and scale across future projects.
|
|
231
|
+
|
|
232
|
+
## Current State
|
|
233
|
+
|
|
234
|
+
Completed:
|
|
235
|
+
|
|
236
|
+
- release-readiness checks are wired into CI
|
|
237
|
+
- JS and Python are thin wrappers over the Rust core
|
|
238
|
+
- the Rust core now provides `version`, `validate`, `sync`, `create`, and `init`
|
|
239
|
+
- `ossplate.toml` is the canonical identity source for owned metadata surfaces
|
|
240
|
+
- installed npm and Python artifacts now carry the staged scaffold payload for `create` and `init`
|
|
241
|
+
- artifact smoke tests prove installed distributions can run `version`, `create`, and `validate`
|
|
242
|
+
- scaffold payload staging is now driven by an explicit curated manifest instead of a broad repo snapshot
|
|
243
|
+
- Python packaging stages distribution assets through its build hook
|
|
244
|
+
- CI now enforces Rust formatting and clippy alongside the existing test/package checks
|
|
245
|
+
|
|
246
|
+
## Next Steps
|
|
247
|
+
|
|
248
|
+
- expand `sync` ownership carefully beyond the root README identity block and into selected workflow identity fields where safe
|
|
249
|
+
- improve `validate` and `sync --check` output further if diff-style rendering becomes necessary
|
|
250
|
+
- keep the root verification workflow aligned with CI as new checks are added
|
|
251
|
+
- harden publish workflows with the OIDC-first fallback strategy from Phase 3
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "Ossplate"
|
|
3
|
+
description = "A practical baseline for shipping one project across Cargo, npm, and PyPI without starting from scratch every time."
|
|
4
|
+
repository = "https://github.com/stefdevscore/ossplate"
|
|
5
|
+
license = "Unlicense"
|
|
6
|
+
|
|
7
|
+
[author]
|
|
8
|
+
name = "Stef"
|
|
9
|
+
email = "stefdevscore@github.com"
|
|
10
|
+
|
|
11
|
+
[packages]
|
|
12
|
+
rust_crate = "ossplate"
|
|
13
|
+
npm_package = "ossplate"
|
|
14
|
+
python_package = "ossplate"
|
|
15
|
+
command = "ossplate"
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
5
|
+
|
|
6
|
+
find_python() {
|
|
7
|
+
local candidate
|
|
8
|
+
for candidate in python3.14 python3.13 python3.12 python3.11 python3.10 python3; do
|
|
9
|
+
if command -v "$candidate" >/dev/null 2>&1; then
|
|
10
|
+
if "$candidate" -c 'import sys; raise SystemExit(0 if sys.version_info >= (3, 10) else 1)' >/dev/null 2>&1; then
|
|
11
|
+
printf '%s\n' "$candidate"
|
|
12
|
+
return 0
|
|
13
|
+
fi
|
|
14
|
+
fi
|
|
15
|
+
done
|
|
16
|
+
printf 'verify.sh: no Python 3.10+ interpreter found on PATH\n' >&2
|
|
17
|
+
return 1
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
PYTHON_BIN="$(find_python)"
|
|
21
|
+
|
|
22
|
+
run_step() {
|
|
23
|
+
local label="$1"
|
|
24
|
+
shift
|
|
25
|
+
printf '\n[%s]\n' "$label"
|
|
26
|
+
"$@"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
run_step "rust:fmt" cargo fmt --check --manifest-path "$ROOT_DIR/core-rs/Cargo.toml"
|
|
30
|
+
run_step "rust:clippy" cargo clippy --manifest-path "$ROOT_DIR/core-rs/Cargo.toml" -- -D warnings
|
|
31
|
+
run_step "rust:test" cargo test --manifest-path "$ROOT_DIR/core-rs/Cargo.toml"
|
|
32
|
+
run_step "tool:validate" cargo run --quiet --manifest-path "$ROOT_DIR/core-rs/Cargo.toml" -- validate --path "$ROOT_DIR" --json
|
|
33
|
+
run_step "tool:sync-check" cargo run --quiet --manifest-path "$ROOT_DIR/core-rs/Cargo.toml" -- sync --path "$ROOT_DIR" --check
|
|
34
|
+
run_step "js:test" bash -lc "cd \"$ROOT_DIR/wrapper-js\" && npm test"
|
|
35
|
+
run_step "js:pack" bash -lc "cd \"$ROOT_DIR/wrapper-js\" && npm pack --dry-run"
|
|
36
|
+
run_step "py:test" bash -lc "cd \"$ROOT_DIR/wrapper-py\" && PYTHONPATH=src \"$PYTHON_BIN\" -m unittest discover -s tests -p 'test_*.py'"
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# JavaScript Wrapper For Ossplate
|
|
2
|
+
|
|
3
|
+
This package is the JavaScript wrapper surface for Ossplate.
|
|
4
|
+
|
|
5
|
+
It delegates to the canonical Rust binary instead of implementing its own CLI behavior.
|
|
6
|
+
|
|
7
|
+
Use `OSSPLATE_BINARY` during local development to point the wrapper at a specific binary.
|
|
Binary file
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ossplate",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"lockfileVersion": 3,
|
|
5
|
+
"requires": true,
|
|
6
|
+
"packages": {
|
|
7
|
+
"": {
|
|
8
|
+
"name": "ossplate",
|
|
9
|
+
"version": "0.1.0",
|
|
10
|
+
"license": "Unlicense",
|
|
11
|
+
"bin": {
|
|
12
|
+
"ossplate": "bin/ossplate.js"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@types/node": "^24.6.0",
|
|
16
|
+
"typescript": "^5.9.3"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"node_modules/@types/node": {
|
|
20
|
+
"version": "24.12.0",
|
|
21
|
+
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.0.tgz",
|
|
22
|
+
"integrity": "sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==",
|
|
23
|
+
"dev": true,
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"undici-types": "~7.16.0"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"node_modules/typescript": {
|
|
30
|
+
"version": "5.9.3",
|
|
31
|
+
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
|
32
|
+
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
|
33
|
+
"dev": true,
|
|
34
|
+
"license": "Apache-2.0",
|
|
35
|
+
"bin": {
|
|
36
|
+
"tsc": "bin/tsc",
|
|
37
|
+
"tsserver": "bin/tsserver"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=14.17"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"node_modules/undici-types": {
|
|
44
|
+
"version": "7.16.0",
|
|
45
|
+
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
|
|
46
|
+
"integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
|
|
47
|
+
"dev": true,
|
|
48
|
+
"license": "MIT"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|