17 Commits

Author SHA1 Message Date
af3c82518c Change go package name
All checks were successful
Generate and Release Protos / release (push) Successful in 26s
2026-01-08 23:30:56 +00:00
9511db8ee9 Set correct package name for Go package generation
All checks were successful
Generate and Release Protos / release (push) Successful in 26s
2026-01-08 23:15:48 +00:00
fc92331238 Try and fix AGAIN
All checks were successful
Generate and Release Protos / release (push) Successful in 26s
2026-01-08 23:06:45 +00:00
a4e6386fd1 Attempt to fix internal ZIP structure again?
All checks were successful
Generate and Release Protos / release (push) Successful in 26s
2026-01-08 22:55:15 +00:00
3199037c5a Fix structure of internal ZIP file for the Go release
All checks were successful
Generate and Release Protos / release (push) Successful in 25s
2026-01-08 22:47:30 +00:00
a78e749d55 Fix the Go version string
All checks were successful
Generate and Release Protos / release (push) Successful in 28s
2026-01-08 22:38:59 +00:00
fb4d7b2ed6 Remove translates proto files 2026-01-07 20:13:02 +00:00
3d750b1b18 Add MQFileIpdate schema (Currently supporting PIS only) 2026-01-07 20:09:10 +00:00
f9463f3d29 Update README 2026-01-07 18:46:15 +00:00
7fe1be9b48 Workflow fix
All checks were successful
Generate and Release Protos / release (push) Successful in 25s
2026-01-07 18:36:32 +00:00
c8731caadd Fix again
Some checks failed
Generate and Release Protos / release (push) Failing after 22s
2026-01-07 18:28:34 +00:00
20cb7b101c Try fix workflow
Some checks failed
Generate and Release Protos / release (push) Failing after 23s
2026-01-07 18:25:43 +00:00
ac3124ff14 Adjust workflow for correct module generation
Some checks failed
Generate and Release Protos / release (push) Failing after 23s
2026-01-07 18:23:17 +00:00
b29f42c004 Fix script call
Some checks failed
Generate and Release Protos / release (push) Failing after 25s
2026-01-07 17:29:01 +00:00
051721ce02 Fix go module installation
Some checks failed
Generate and Release Protos / release (push) Failing after 32s
2026-01-07 17:26:49 +00:00
04ed0ede29 Switch to JSON Schema rather than protobuf
Some checks failed
Generate and Release Protos / release (push) Failing after 9s
2026-01-07 17:23:56 +00:00
a17e7a5290 Update buf.gen.yaml
All checks were successful
Generate and Release Protos / release (push) Successful in 22s
2026-01-07 15:59:19 +00:00
10 changed files with 194 additions and 148 deletions

View File

@@ -17,14 +17,9 @@ jobs:
id: get_version id: get_version
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
- uses: bufbuild/buf-action@v1.3
with:
setup_only: true
version: '1.63.0'
- uses: actions/setup-go@v5 - uses: actions/setup-go@v5
with: with:
go-version: '1.23' go-version: '1.24'
- uses: actions/setup-node@v6 - uses: actions/setup-node@v6
with: with:
@@ -32,73 +27,75 @@ jobs:
registry-url: 'https://git.fjla.uk/api/packages/owlboard/npm' registry-url: 'https://git.fjla.uk/api/packages/owlboard/npm'
scope: '@owlboard' scope: '@owlboard'
- name: Install Go Protoc Plugin - name: Install Generators
run: | run: |
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest npm install -g json-schema-to-typescript typescript
go install github.com/atombender/go-jsonschema@latest
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
- name: Install TS-Proto Plugin - run: bash scripts/build.sh
run: |
npm install ts-proto typescript
echo "$PATH:$(pwd)/ts-proto" >> $GITHUB_PATH
- name: Generate Code
run: buf generate
- name: Build and Publish TS - name: Build and Publish TS
working-directory: gen/ts working-directory: gen/ts
run: | run: |
npm init -y npm init -y
# 1. Create a dynamic index.ts using Namespace exports # Build index.ts
# This converts 'rail_backend/v1/pis_mapping.ts' echo "// Auto-generated" > index.ts
# into 'export * as PisMapping from "./rail_backend/v1/pis_mapping";' find . -maxdepth 1 -name "*.ts" -not -name "index.ts" | sed 's|^\./||; s|\.ts$||' | awk '{
# We use awk to handle the naming conversion (snake_case to PascalCase-ish) # Use gsub to turn hyphens into underscores so we can split easily
find . -name "*.ts" -not -name "index.ts" | sed 's|^\./||; s|\.ts$||' | awk -F'/' '{ clean = $0;
name=$NF; gsub(/-/, "_", clean);
gsub(/_/, "", name);
printf "export * as %s from \"./%s\";\n", toupper(substr(name,1,1)) substr(name,2), $0
}' > index.ts
# 2. Update package.json n = split(clean, parts, "_");
jq '.name = "@owlboard/backend-data-contracts" | name = "";
.version = "${{ steps.get_version.outputs.VERSION }}" | for (i=1; i<=n; i++) {
.type = "module" | if (length(parts[i]) > 0) {
.main = "./dist/index.js" | name = name toupper(substr(parts[i],1,1)) substr(parts[i],2);
.types = "./dist/index.d.ts" | }
.publishConfig = { "registry": "https://git.fjla.uk/api/packages/owlboard/npm" }' \ }
package.json > temp.json && mv temp.json package.json # name will now be 'DataIngressPisData' (valid TS)
printf "export * as %s from \"./%s.js\";\n", name, $0
}' >> index.ts
# 3. Compile VERSION="${{ steps.get_version.outputs.VERSION }}"
npx tsc index.ts --declaration --module esnext --target es2022 --moduleResolution node --outDir dist/ jq --arg ver "$VERSION" \
--arg name "@owlboard/backend-data-contracts" \
'.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 npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.PACKAGE_PUSH }}
- name: Publish Go - name: Publish Go
run: | run: |
# 1. Setup variables VERSION="v${{ steps.get_version.outputs.VERSION }}"
VERSION="${{ steps.get_version.outputs.VERSION }}"
MOD_NAME="git.fjla.uk/owlboard/backend-data-contracts" MOD_NAME="git.fjla.uk/owlboard/backend-data-contracts"
# Create a temporary directory structure that matches Go proxy requirements ZIP_ROOT="/tmp/go_upload"
DEST_DIR="temp_zip/$MOD_NAME@$VERSION" FULL_PATH="$ZIP_ROOT/$MOD_NAME@$VERSION"
# 2. Generate go.mod and tidy # 1. Prepare
cd gen/go cd gen/go
go mod init $MOD_NAME
go mod tidy
# 3. Move files into the required nested structure # 2. Initialize the module
mkdir -p "../../$DEST_DIR" go mod init "$MOD_NAME"
cp -r . "../../$DEST_DIR/"
# 4. Zip from the temp root so the internal paths are correct # 3. Create the structure
cd ../../temp_zip mkdir -p "$FULL_PATH"
zip -r ../module.zip .
# 5. Upload with the explicit version # 4. Copy the CONTENTS of models to the root of the module
cd .. # This flattens the structure so the .go files are next to go.mod
curl -f -v --user "owlbot:${{ secrets.PACKAGE_PUSH }}" \ cp -r models/* "$FULL_PATH/"
--upload-file module.zip \ 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" "${{ github.server_url }}/api/packages/owlboard/go/upload?version=$VERSION"

View File

@@ -1,32 +1,18 @@
# backend-data-contracts # backend-data-contracts
This repository is the single source of truth for all Protocol Buffer (Protobuf) schema definitions used across the Owlboard Rail Ingress and Processing microservices. It follows a **Contract-First** approach, where language-specific code (Go, TypeScript) is generated and distributed via private registries. This repository is the single source of truth for all schema definitions used across the Owlboard backend communication and storage services. Language specific types are generated here and published to the Gitea package repository linked to the repo.
## Purpose
The Protobuf files defined here serve as the immutable data contract for:
1. **Ingress Logic:** Ensuring the Node.js and Go inregrate properly by sharing types.
2. **Message Payloads:** Defining messages for cross-service communication.
3. **Persistence:** Defining the expected structure of documents in MongoDB for the Go processing services.
## Directory Structure ## Directory Structure
| Path | Description | Contents | | Path | Description |
| :--- | :--- | :--- | | :--- | :--- |
| `proto/` | **Source of Truth.** Contains the Protobuf schema definitions. | `rail_backend/v1/*.proto` | | `schemas` | JSON Schema files organised into clear subfolders |
| `buf.yaml` | **Workspace Config.** Defines linting and breaking change rules (Buf v2). | Workspace settings | | `scripts` | Workflow Scripts |
| `buf.gen.yaml` | **Generation Config.** Defines how Go and TS code is built. | Plugin & Managed Mode settings |
| `gen/` | **Transient Output.** Generated code resides here during CI/CD. | `.pb.go`, `.js`, `.d.ts` (**Git Ignored**) |
## Code Generation and Publishing Workflow ## Code Generation and Publishing Workflow
The generation and release process is automated via Gitea Actions. It is triggered whenever a new **SemVer tag** (e.g., `v1.0.0`) is pushed to this repository. The generation and release process is automated via Gitea Actions. It is triggered whenever a new **SemVer tag** (e.g., `v1.0.0`) is pushed to this repository.
1. **Validation:** `buf lint` ensures schemas follow best practices.
2. **Generation:** `buf generate` creates Go and TypeScript code using local plugins.
3. **TS Release:** Compiles `.ts` to `.js` and publishes to the Gitea NPM Registry as `@owlboard/backend-data-contracts`.
4. **Go Release:** Initializes a `go.mod`, zips the artifacts, and pushes them to the Gitea Go Package Registry.
## To Consume the Contracts ## To Consume the Contracts
### 1. Go Services ### 1. Go Services
@@ -35,3 +21,17 @@ Since the package is hosted in the Gitea Package Registry, you must configure yo
**Setup:** **Setup:**
```bash ```bash
export GOPROXY=[https://git.fjla.uk/api/packages/owlboard/go,https://proxy.golang.org,direct](https://git.fjla.uk/api/packages/owlboard/go,https://proxy.golang.org,direct) export GOPROXY=[https://git.fjla.uk/api/packages/owlboard/go,https://proxy.golang.org,direct](https://git.fjla.uk/api/packages/owlboard/go,https://proxy.golang.org,direct)
```
### 2. Typescript Services
You will need to configure .npmrc in your projects root directory to point to the correct repo:
```bash
@owlboard:registry=https://git.fjla.uk/api/packages/OwlBoard/npm/
```
Then you can install as usual:
```bash
npm install @owlboard/backend-data-contracts@0.1.0
```

View File

@@ -1,17 +0,0 @@
version: v2
managed:
enabled: true
override:
- file_option: go_package_prefix
value: github.com/owlboard/backend-data-contracts
plugins:
- local: protoc-gen-go
out: gen/go
opt: paths=source_relative
- local: ./node_modules/ts-proto/protoc-gen-ts_proto
out: gen/ts
opt:
- esModuleInterop=true
- outputJsonMethods=true
- forceLong=string
- importSuffix=.js

View File

@@ -1,9 +0,0 @@
version: v2
modules:
- path: protos
lint:
use:
- DEFAULT
breaking:
use:
- FILE

View File

@@ -1,10 +0,0 @@
syntax = "proto3";
package rail_backend.v1;
message Metadata {
int64 push_to_queue_time = 1;
int64 data_fetch_time = 2;
map<string, string> tags = 3;
}

View File

@@ -1,16 +0,0 @@
syntax = "proto3";
package rail_backend.v1;
message PisReferenceList {
repeated PisMapping entries = 1;
}
message PisMapping {
string code = 1;
string toc = 2;
repeated string crsStops = 3;
fixed64 crsHash = 4; // XXH4 Hash for fast lookup of exact match
repeated string tiplocStops = 5;
fixed64 tiplocHash = 6;
}

View File

@@ -1,20 +0,0 @@
syntax = "proto3";
package rail_backend.v1;
import "rail_backend/v1/common.proto";
import "rail_backend/v1/schedule_payload.proto";
message IngressMessage {
string correlation_id = 1;
Metadata tracking_data = 2;
oneof payload {
UrlReference url_ref = 5;
SchedulePayload schedule_payload = 6;
}
}
message UrlReference {
string kind = 1;
string url = 2;
}

View File

@@ -0,0 +1,42 @@
{
"$id": "https://schema.owlboard.info/data-ingress/mq-file-update.schema.json",
"$schema": "https://json-schema.org/draft-07/schema#",
"title": "MQFileUpdate",
"type": "object",
"properties": {
"service_name": {
"type": "string",
"description": "Name of the service submitting the update"
},
"update_type": {
"type": "string",
"enum": ["file"],
"description": "The method of update application"
},
"sent_timestamp": {
"type": "integer",
"description": "Unix timestamp representing the time the message was sent"
},
"payload": {
"type": "object",
"properties": {
"kind": {
"type": "string",
"enum": ["pis"],
"description": "The type of data provided in the update"
},
"version": {
"type": "string",
"description": "The version string from the package source"
},
"filepath": {
"type": "string",
"description": "The full path to the file, including protocol (eg. s3://) where appropriate"
}
},
"required": ["kind", "version", "filepath"]
}
},
"required": ["service_name", "update_type", "payload"],
"additionalProperties": false
}

View File

@@ -0,0 +1,54 @@
{
"$id": "https://schema.owlboard.info/data-ingress/pis-data.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"
},
"crsHash": {
"type": "string",
"minLength": 1,
"maxLength": 64,
"pattern": "^[0-9]+$",
"description": "Stringified 64-bit hash"
},
"tiplocStops": {
"type": "array",
"items": {
"type": "string",
"minLength": 4,
"maxLength": 7,
"pattern": "^[a-zA-Z0-9]+$"
},
"description": "List of TIPLOC Codes"
},
"tiplocHash": {
"type": "string",
"minLength": 1,
"maxLength": 64,
"pattern": "^[0-9]+$"
}
},
"required": ["code", "toc", "crsStops", "crsHash", "tiplocStops", "tiplocHash"],
"additionalProperties": false
}

25
scripts/build.sh Normal file
View File

@@ -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"