From 002a38468f3284f099bc420de351637391295b2a Mon Sep 17 00:00:00 2001 From: bcdxn <5067649+bcdxn@users.noreply.github.com> Date: Tue, 22 Sep 2026 12:16:24 -0400 Subject: [PATCH 1/2] feat: add npm specification distribution --- .../workflows/npm-publish-specification.yaml | 65 +++++++++++++++++++ npm/specification/README.md | 39 +++++++++++ npm/specification/package.json.tmpl | 27 ++++++++ 3 files changed, 131 insertions(+) create mode 100644 .github/workflows/npm-publish-specification.yaml create mode 100644 npm/specification/README.md create mode 100644 npm/specification/package.json.tmpl diff --git a/.github/workflows/npm-publish-specification.yaml b/.github/workflows/npm-publish-specification.yaml new file mode 100644 index 0000000..a66633b --- /dev/null +++ b/.github/workflows/npm-publish-specification.yaml @@ -0,0 +1,65 @@ +name: Publish Specification + +on: + push: + tags: + - "spec/v*" + +permissions: + contents: read + id-token: write + +jobs: + publish: + name: Publish @openclidev/specification + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v7 + with: + fetch-depth: 0 + + - name: Setup Node + uses: actions/setup-node@v6 + with: + node-version: 24 + registry-url: https://registry.npmjs.org + + - name: Extract version + id: version + env: + TAG: ${{ github.ref_name }} + run: | + VERSION="${TAG#spec/v}" + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + echo "Publishing version: $VERSION" + + - name: Prepare package + env: + VERSION: ${{ steps.version.outputs.version }} + run: | + mkdir -p npm/specification/schema + + cp spec.schema.json \ + npm/specification/schema/opencli.schema.json + + sed "s/###VERSION###/$VERSION/g" \ + npm/specification/package.json.template \ + > npm/specification/package.json + + - name: Verify package + working-directory: npm/specification + run: | + echo "Generated package.json:" + cat package.json + + echo + echo "Package contents:" + npm pack --dry-run + + test -f schema/opencli.schema.json + + # - name: Publish + # working-directory: npm/specification + # run: npm publish --provenance --access public \ No newline at end of file diff --git a/npm/specification/README.md b/npm/specification/README.md new file mode 100644 index 0000000..aef59d6 --- /dev/null +++ b/npm/specification/README.md @@ -0,0 +1,39 @@ +# @openclidev/specification + +The canonical JSON Schema for the [OpenCLI](https://opencli.dev) specification. + +Use this package to validate OpenCLI documents or build tools and integrations that consume the specification. + +## Installation + +```bash +npm install @openclidev/specification +``` + +## Usage + +Import the schema directly: + +```typescript +import schema from "@openclidev/specification"; +``` + +Or reference the schema file: + +```text +@openclidev/specification/schema/opencli.schema.json +``` + +The schema is also available via the `schema` export: + +```typescript +import schema from "@openclidev/specification/schema"; +``` + +## Source of Truth + +The OpenCLI specification and its JSON Schema are maintained in the [OpenCLI repository](https://github.com/openclidev/opencli). This package is a distribution of the canonical schema for use by tools and implementations across the [ecosystem](https://github.com/bcdxn/opencli#ecosystem). + +## License + +MIT diff --git a/npm/specification/package.json.tmpl b/npm/specification/package.json.tmpl new file mode 100644 index 0000000..76ac51e --- /dev/null +++ b/npm/specification/package.json.tmpl @@ -0,0 +1,27 @@ +{ + "name": "@openclidev/specification", + "version": "###VERSION###", + "description": "The canonical JSON Schema for the OpenCLI specification.", + "license": "MIT", + "files": [ + "schema", + "README.md", + "LICENSE" + ], + "exports": { + ".": "./schema/opencli.schema.json", + "./schema": "./schema/opencli.schema.json", + "./schema/opencli.schema.json": "./schema/opencli.schema.json", + "./package.json": "./package.json" + }, + "keywords": [ + "opencli", + "cli", + "specification", + "json-schema", + "cli-specification" + ], + "publishConfig": { + "access": "public" + } +} From 7208e62e39f3d44afc23953e093684889fe12fd0 Mon Sep 17 00:00:00 2001 From: bcdxn <5067649+bcdxn@users.noreply.github.com> Date: Tue, 22 Sep 2026 13:16:16 -0400 Subject: [PATCH 2/2] fix: npm distribution workflow --- .../workflows/npm-publish-specification.yaml | 51 ++++++++++++++++--- npm/specification/README.md | 2 +- npm/specification/package.json.tmpl | 2 +- 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/.github/workflows/npm-publish-specification.yaml b/.github/workflows/npm-publish-specification.yaml index a66633b..af7706b 100644 --- a/.github/workflows/npm-publish-specification.yaml +++ b/.github/workflows/npm-publish-specification.yaml @@ -31,9 +31,43 @@ jobs: env: TAG: ${{ github.ref_name }} run: | + if [[ ! "$TAG" =~ ^spec/v.+$ ]]; then + echo "ERROR: Invalid specification tag: $TAG" + exit 1 + fi + VERSION="${TAG#spec/v}" + + SCHEMA_VERSION="$(jq -r ' + .properties.opencliVersion.enum as $versions + | if ($versions | type) == "array" and ($versions | length) == 1 and ($versions[0] | type) == "string" + then $versions[0] + else empty + end + ' spec.schema.json)" + + if [[ -z "$SCHEMA_VERSION" ]]; then + echo "ERROR: Could not determine the schema version from spec.schema.json" + exit 1 + fi + + if [[ "$VERSION" != "$SCHEMA_VERSION" ]]; then + echo "ERROR: Tag version $VERSION does not match schema version $SCHEMA_VERSION" + exit 1 + fi + echo "version=$VERSION" >> "$GITHUB_OUTPUT" - echo "Publishing version: $VERSION" + + if [[ "$VERSION" =~ -([a-zA-Z]+)\.[0-9]+$ ]]; then + DIST_TAG="${BASH_REMATCH[1]}" + else + DIST_TAG="latest" + fi + + echo "dist_tag=$DIST_TAG" >> "$GITHUB_OUTPUT" + + echo "Version: $VERSION" + echo "Dist tag: $DIST_TAG" - name: Prepare package env: @@ -44,8 +78,10 @@ jobs: cp spec.schema.json \ npm/specification/schema/opencli.schema.json - sed "s/###VERSION###/$VERSION/g" \ - npm/specification/package.json.template \ + cp LICENSE npm/specification/LICENSE + + sed "s|{{VERSION}}|$VERSION|g" \ + npm/specification/package.json.tmpl \ > npm/specification/package.json - name: Verify package @@ -59,7 +95,10 @@ jobs: npm pack --dry-run test -f schema/opencli.schema.json + test -f LICENSE - # - name: Publish - # working-directory: npm/specification - # run: npm publish --provenance --access public \ No newline at end of file + - name: Publish + working-directory: npm/specification + env: + DIST_TAG: ${{ steps.version.outputs.dist_tag }} + run: npm publish --provenance --access public --tag "$DIST_TAG" \ No newline at end of file diff --git a/npm/specification/README.md b/npm/specification/README.md index aef59d6..d41ac5e 100644 --- a/npm/specification/README.md +++ b/npm/specification/README.md @@ -32,7 +32,7 @@ import schema from "@openclidev/specification/schema"; ## Source of Truth -The OpenCLI specification and its JSON Schema are maintained in the [OpenCLI repository](https://github.com/openclidev/opencli). This package is a distribution of the canonical schema for use by tools and implementations across the [ecosystem](https://github.com/bcdxn/opencli#ecosystem). +The OpenCLI specification and its JSON Schema are maintained in the [OpenCLI repository](https://github.com/bcdxn/opencli). This package is a distribution of the canonical schema for use by tools and implementations across the [ecosystem](https://github.com/bcdxn/opencli#ecosystem). ## License diff --git a/npm/specification/package.json.tmpl b/npm/specification/package.json.tmpl index 76ac51e..ba019e3 100644 --- a/npm/specification/package.json.tmpl +++ b/npm/specification/package.json.tmpl @@ -1,6 +1,6 @@ { "name": "@openclidev/specification", - "version": "###VERSION###", + "version": "{{VERSION}}", "description": "The canonical JSON Schema for the OpenCLI specification.", "license": "MIT", "files": [