23 Commits

Author SHA1 Message Date
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
aab04bb194 Fix import difficulties in typescript
All checks were successful
Generate and Release Protos / release (push) Successful in 23s
2026-01-07 15:46:51 +00:00
1e0b3cc574 Update Go Publishing step
All checks were successful
Generate and Release Protos / release (push) Successful in 22s
2026-01-07 14:40:30 +00:00
cf2609f624 Add verbose logging for curl output in the Publish Go job
Some checks failed
Generate and Release Protos / release (push) Failing after 21s
2026-01-07 14:30:57 +00:00
ab31c84913 Fix Go publishing step to handle URL properly
All checks were successful
Generate and Release Protos / release (push) Successful in 21s
2026-01-07 14:07:56 +00:00
018190f76b Fix NPM Step
Some checks failed
Generate and Release Protos / release (push) Failing after 22s
2026-01-07 14:04:45 +00:00
affdb052b2 Try and update npm build & publish step
Some checks failed
Generate and Release Protos / release (push) Failing after 21s
2026-01-07 13:52:38 +00:00
90fe8be81d Update tsc command
Some checks failed
Generate and Release Protos / release (push) Failing after 20s
2026-01-07 13:37:56 +00:00
9c27e46bfb Update tsc command
Some checks failed
Generate and Release Protos / release (push) Failing after 20s
2026-01-07 13:34:21 +00:00
e3877bc7c0 Update path to protoc-gen-go
Some checks failed
Generate and Release Protos / release (push) Failing after 18s
2026-01-07 13:32:12 +00:00
c876637720 Update buildbuf version
Some checks failed
Generate and Release Protos / release (push) Failing after 19s
2026-01-07 13:29:11 +00:00
7fd7d94572 Set specific big version
Some checks failed
Generate and Release Protos / release (push) Failing after 5s
2026-01-07 13:27:19 +00:00
d6c5750d5e Move to new buf-action
Some checks failed
Generate and Release Protos / release (push) Failing after 9s
2026-01-07 13:25:07 +00:00
2068a4335b Update directory name to cover the correct package name
Some checks failed
Generate and Release Protos / release (push) Failing after 23s
2026-01-07 13:17:02 +00:00
7e2361015a Ugrade generation steps to use bufv2, and Gitea Go package registry. 2026-01-07 13:15:14 +00:00
59e405d2c4 Update package name 2026-01-06 21:05:31 +00:00
12 changed files with 187 additions and 102 deletions

View File

@@ -16,59 +16,84 @@ jobs:
- name: Get Version - name: Get Version
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-setup-action@v1
- 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:
node-version: '18.18.x' node-version: '18.18.x'
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
echo "$PATH:$(pwd)/ts-proto" >> $GITHUB_PATH
- name: Generate Code - name: Build and Publish TS
run: buf generate
- name: Publish TS
working-directory: gen/ts working-directory: gen/ts
run: | run: |
npm init -y npm init -y
jq '.name = "@owlboard/backend-data-contracts" |
.version = "${{ steps.get_version.outputs.VERSION }}" | # Build index.ts
.description = "Generated Protobuf types for data ingress services" | echo "// Auto-generated" > index.ts
.repository = { find . -maxdepth 1 -name "*.ts" -not -name "index.ts" | sed 's|^\./||; s|\.ts$||' | awk '{
"type": "git", # Use gsub to turn hyphens into underscores so we can split easily
"url": "git+https://${{ github.server_url }}/${{ github.repository }}.git" clean = $0;
} | gsub(/-/, "_", clean);
.bugs = {
"url": "https://${{ github.server_url }}/${{ github.repository }}/issues" n = split(clean, parts, "_");
} | name = "";
.homepage = "https://${{ github.server_url }}/${{ github.repository }}#readme"' \ for (i=1; i<=n; i++) {
package.json > temp.json && mv temp.json package.json if (length(parts[i]) > 0) {
npm publish name = name toupper(substr(parts[i],1,1)) substr(parts[i],2);
env: }
NODE_AUTH_TOKEN: ${{ secrets.PACKAGE_PUSH }} }
# name will now be 'DataIngressPisData' (valid TS)
printf "export * as %s from \"./%s.js\";\n", name, $0
}' >> index.ts
- name: Commit Generated Go VERSION="${{ steps.get_version.outputs.VERSION }}"
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
- name: Publish Go
run: | run: |
git config user.name "owlbot" # 1. Setup variables
git config user.email "owlbot@owlboard.info" VERSION="${{ steps.get_version.outputs.VERSION }}"
git add gen/go/*.go MOD_NAME="git.fjla.uk/owlboard/backend-data-contracts"
git commit -m "OwlBot: Generated go types for ${{ steps.get_version.outputs.VERSION }}" # Create a temporary directory structure that matches Go proxy requirements
git diff-index --quiet HEAD || git commit -m "OwlBot: Generated go types for ${{ steps.get_version.outputs.VERSION }}" DEST_DIR="temp_zip/$MOD_NAME@$VERSION"
git push origin HEAD:refs/tags/${{ github.ref_name }} --force
env: # 2. Generate go.mod and tidy
GITHUB_TOKEN: ${{ secrets.REPO_PUSH }} cd gen/go
go mod init $MOD_NAME
go mod tidy
# 3. Move files into the required nested structure
mkdir -p "../../$DEST_DIR"
cp -r . "../../$DEST_DIR/"
# 4. Zip from the temp root so the internal paths are correct
cd ../../temp_zip
zip -r ../module.zip .
# 5. Upload with the explicit version
cd ..
curl -f -v --user "owlbot:${{ secrets.PACKAGE_PUSH }}" \
--upload-file module.zip \
"${{ github.server_url }}/api/packages/owlboard/go/upload?version=$VERSION"

View File

@@ -1,34 +1,37 @@
# data-contracts # backend-data-contracts
This repository is the single source of truth for all Protocol Buffer (Protobuf) schema definitions used across the Rail Ingress and Processing microservices. 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.
## Purpose ## Purpose
The Protobuf files defined here serve as the immutable data contract for: The Protobuf files defined here serve as the immutable data contract for:
1. **Message Queue Payloads:** Defining messages pushed to the Artemis queue (Go Process Service consumption). 1. **Ingress Logic:** Ensuring the Node.js and Go inregrate properly by sharing types.
2. **Database Schemas:** Defining the expected structure of documents in MongoDB (Go Process and TypeScript API service consumption). 2. **Message Payloads:** Defining messages for cross-service communication.
3. **Cross-Service Communication:** Ensuring type-safe data exchange between all polyglot services (Go, TypeScript). 3. **Persistence:** Defining the expected structure of documents in MongoDB for the Go processing services.
## Directory Structure and Artifacts ## Directory Structure
| Path | Description | Contents | | Path | Description | Contents |
| :--- | :--- | :--- | | :--- | :--- | :--- |
| `protos/rail/v1/` | **Source Code.** Contains all source `.proto` files. **Only these files reside on the `main` branch.** | `.proto` files | | `proto/` | **Source of Truth.** Contains the Protobuf schema definitions. | `rail_backend/v1/*.proto` |
| `ts/` | **Generated TypeScript/JavaScript code.** Used as the root for the NPM package publish. **Not committed to Git.** | `package.json`, generated `.js`, `.d.ts` | | `buf.yaml` | **Workspace Config.** Defines linting and breaking change rules (Buf v2). | Workspace settings |
| `go.mod` | Defines the Go Module path: `git.fjla.uk/owlboard/backend-data-contracts`. | Go Module definition | | `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 (Gitea Action) ## Code Generation and Publishing Workflow
The generation process is automated via a Gitea Action (`.gitea/workflows/generate_contracts.yml`), which runs when a change is pushed to a source `.proto` file. 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 action performs the following steps: 1. **Validation:** `buf lint` ensures schemas follow best practices.
1. Generates all Go and TypeScript/JavaScript artifacts. 2. **Generation:** `buf generate` creates Go and TypeScript code using local plugins.
2. **Go Artifacts:** Commits the generated `*.pb.go` files to a **new Git tag** (e.g., `v1.0.1`), ensuring the `main` branch remains clean. 3. **TS Release:** Compiles `.ts` to `.js` and publishes to the Gitea NPM Registry as `@owlboard/backend-data-contracts`.
3. **TypeScript Artifacts:** Packages the generated files and publishes the corresponding version (e.g., `1.0.1`) to the internal NPM registry. 4. **Go Release:** Initializes a `go.mod`, zips the artifacts, and pushes them to the Gitea Go Package Registry.
### To Consume the Contract: ## To Consume the Contracts
| Language | Artifact | Consumption Method | ### 1. Go Services
| :--- | :--- | :--- | Since the package is hosted in the Gitea Package Registry, you must configure your environment to use the Gitea instance as a proxy.
| **Go** | Source Code (`*.pb.go`) | **Requires a Git Tag.** Update your service's `go.mod` file to reference the desired tag: `git.fjla.uk/owlboard/backend-data-contracts v1.0.1`. |
| **TypeScript** | NPM Package | Update the version in your `package.json` file and install: `"@owlboard/contracts": "1.0.1"`. | **Setup:**
```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)

View File

@@ -1,12 +0,0 @@
version: v1
plugins:
- plugin: go
out: gen/go
opt: paths=source_relative
- plugin: ts-proto
path: ./node_modules/ts-proto/protoc-gen-ts_proto
out: gen/ts
opt:
- esModuleInterop=true
- outputJsonMethods=true
- forceLong=string

View File

@@ -1,4 +0,0 @@
# buf.work.yaml
version: v1
directories:
- protos

3
go.mod
View File

@@ -1,3 +0,0 @@
module git.fjla.uk/owlboard/backend-data-contracts
go 1.24.10

View File

@@ -1,15 +0,0 @@
syntax = "proto3";
package rail.v1;
option go_package = "git.fjla.uk/owlboard/backend-data-contracts";
message PisReferenceList {
repeated PisMapping entries = 1;
}
message PisMapping {
string code = 1;
string operator = 2;
repeated string stops = 3;
fixed64 stops_xxh4 = 4; // XXH4 Hash for fast lookup of exact match
}

View File

@@ -1,7 +1,6 @@
syntax = "proto3"; syntax = "proto3";
package rail.v1; package rail_backend.v1;
option go_package = "git.fjla.uk/owlboard/generated/go/rail/v1";
message Metadata { message Metadata {
int64 push_to_queue_time = 1; int64 push_to_queue_time = 1;

View File

@@ -0,0 +1,16 @@
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,11 +1,9 @@
syntax = "proto3"; syntax = "proto3";
package rail.v1; package rail_backend.v1;
option go_package = "git.fjla.uk/owlboard/generated/go/rail/v1";
import "rail_backend/v1/common.proto";
import "rail/v1/common.proto"; import "rail_backend/v1/schedule_payload.proto";
import "rail/v1/schedule_payload.proto";
message IngressMessage { message IngressMessage {
string correlation_id = 1; string correlation_id = 1;

View File

@@ -1,7 +1,6 @@
syntax = "proto3"; syntax = "proto3";
package rail.v1; package rail_backend.v1;
option go_package = "git.fjla.uk/owlboard/generated/go/rail/v1";
enum SchedulePayloadType { enum SchedulePayloadType {
VSTP_MESSAGE_TYPE_UNSPECIFIED = 0; VSTP_MESSAGE_TYPE_UNSPECIFIED = 0;

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 models "$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"