diff --git a/.gitea/workflows/release.yaml b/.gitea/workflows/release.yaml new file mode 100644 index 0000000..43a3330 --- /dev/null +++ b/.gitea/workflows/release.yaml @@ -0,0 +1,101 @@ +name: Generate and Release Protos +on: + push: + tags: + - 'v*' + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Get Version + id: get_version + run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT + + - uses: actions/setup-go@v5 + with: + go-version: '1.24' + + - uses: actions/setup-node@v6 + with: + node-version: '18.18.x' + registry-url: 'https://git.fjla.uk/api/packages/owlboard/npm' + scope: '@owlboard' + + - name: Install Generators + run: | + npm install -g json-schema-to-typescript typescript + go install github.com/atombender/go-jsonschema@latest + echo "$(go env GOPATH)/bin" >> $GITHUB_PATH + + - run: bash scripts/build.sh + + - name: Build and Publish TS + working-directory: gen/ts + run: | + npm init -y + + # Build index.ts + echo "// Auto-generated" > index.ts + find . -maxdepth 1 -name "*.ts" -not -name "index.ts" | sed 's|^\./||; s|\.ts$||' | awk '{ + # Use gsub to turn hyphens into underscores so we can split easily + clean = $0; + gsub(/-/, "_", clean); + + n = split(clean, parts, "_"); + name = ""; + for (i=1; i<=n; i++) { + if (length(parts[i]) > 0) { + name = name toupper(substr(parts[i],1,1)) substr(parts[i],2); + } + } + # name will now be 'DataIngressPisData' (valid TS) + printf "export * as %s from \"./%s.js\";\n", name, $0 + }' >> index.ts + + VERSION="${{ steps.get_version.outputs.VERSION }}" + jq --arg ver "$VERSION" \ + --arg name "@owlboard/api-schema-types" \ + '.name = $name | .version = $ver | .type = "module" | .main = "./dist/index.js" | .types = "./dist/index.d.ts"' \ + package.json > package.json.new && mv package.json.new package.json + + # Compile + npx tsc index.ts --declaration --module nodenext --target es2022 --moduleResolution nodenext --outDir dist/ --skipLibCheck true + + # Publish + npm config set //git.fjla.uk/api/packages/owlboard/npm/:_authToken ${{ secrets.PACKAGE_PUSH }} + npm publish + + - name: Publish Go + run: | + VERSION="v${{ steps.get_version.outputs.VERSION }}" + MOD_NAME="git.fjla.uk/owlboard/api-schema-types" + ZIP_ROOT="/tmp/go_upload" + FULL_PATH="$ZIP_ROOT/$MOD_NAME@$VERSION" + + # 1. Prepare + cd gen/go + + # 2. Initialize the module + go mod init "$MOD_NAME" + + # 3. Create the structure + mkdir -p "$FULL_PATH" + + # 4. Copy the CONTENTS of models to the root of the module + # This flattens the structure so the .go files are next to go.mod + cp -r models/* "$FULL_PATH/" + cp go.mod "$FULL_PATH/" + + # 5. Zip and Upload + cd "$ZIP_ROOT" + zip -r -D "$GITHUB_WORKSPACE/module.zip" . + + curl -f --user "owlbot:${{ secrets.PACKAGE_PUSH }}" \ + --upload-file "$GITHUB_WORKSPACE/module.zip" \ + "${{ github.server_url }}/api/packages/owlboard/go/upload?version=$VERSION" \ No newline at end of file diff --git a/schemas/data-ingress/api-envelope.json b/schemas/data-ingress/api-envelope.json new file mode 100644 index 0000000..1d5c505 --- /dev/null +++ b/schemas/data-ingress/api-envelope.json @@ -0,0 +1,46 @@ +{ + "$id": "https://schema.owlboard.info/api/api-envelope.schema.json", + "$schema": "https://json-schema.org/draft-07/schema#", + "title": "ApiEnvelope", + "type": "object", + "properties": { + "t": { + "type": "integer", + "minimum": 0, + "description": "Unix timestamp showing when the data was generated, or the time the error was encountered" + }, + "d": { + "description": "Payload data. Type depends on request endpoint", + "anyOf": [ + {"type": "object"}, + {"type": "array"} + ] + }, + "e": { + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "Type of error encountered", + "enum": [ + "VALIDATION", + "AUTH", + "NOT_FOUND", + "RATE_LIMIT", + "SERVER" + ] + }, + "msg": { + "type": "string", + "description": "Human-readable descriptive error message." + } + } + } + }, + "required": ["t"], + "oneOf": [ + {"required": ["e"]}, + {"required": ["d"]} + ], + "additionalProperties": false +} \ No newline at end of file diff --git a/schemas/data-ingress/pis-object.json b/schemas/data-ingress/pis-object.json new file mode 100644 index 0000000..798f187 --- /dev/null +++ b/schemas/data-ingress/pis-object.json @@ -0,0 +1,41 @@ +{ + "$id": "https://schema.owlboard.info/api/pis-object.schema.json", + "$schema": "https://json-schema.org/draft-07/schema#", + "title": "PisObjects", + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "PIS Code - Code that is entered in to the PIS system" + }, + "toc": { + "type": "string", + "minLength": 2, + "maxLength": 2, + "pattern": "^[a-zA-Z]+$", + "description": "Two letter TOC Code" + }, + "crsStops": { + "type": "array", + "items": { + "type": "string", + "minLength": 3, + "maxLength": 3, + "pattern": "^[a-zA-Z]+$" + }, + "description": "List of 3ALPHA/CRS Codes" + }, + "tiplocStops": { + "type": "array", + "items": { + "type": "string", + "minLength": 4, + "maxLength": 7, + "pattern": "^[a-zA-Z0-9]+$" + }, + "description": "List of TIPLOC Codes" + } + }, + "required": ["code"], + "additionalProperties": false +} \ No newline at end of file diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100644 index 0000000..7417f7e --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,25 @@ +#!/bin/bash +set -e + +# Create clean output directories +rm -rf gen && mkdir -p gen/ts gen/go/models + +# Find all .json files +FILES=$(find schemas -name "*.json") + +# Initialize the TypeScript Barrel File +echo "// Auto-generated barrel file" > gen/ts/index.ts + +for file in $FILES; do + # Get a clean name (e.g., data-ingress_pis-mapping) + clean_name=$(echo "${file#schemas/}" | sed 's/\//_/g' | sed 's/\.json//g') + + # OGenerate TS + npx --yes json-schema-to-typescript "$file" > "gen/ts/${clean_name}.ts" + + # Generate Go + go-jsonschema -p contracts "$file" > "gen/go/models/${clean_name}.go" +done + +echo "✅ Generated single TS package in gen/ts" +echo "✅ Generated single Go package in gen/go/models" \ No newline at end of file