Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@ jobs:
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
run: echo "GPG key loaded"

- name: Build and publish
run: ./gradlew build :preflight-core:preflight-gradle-plugin:publishPlugins :preflight-core:preflight-runtime:publishMavenPublicationToOrbitalRepository :preflight-core:preflight-spec:publishMavenPublicationToOrbitalRepository
- name: Publish preflight-spec
run: cd preflight-spec && ./gradlew build publishMavenPublicationToOrbitalRepository

- name: Build and publish preflight-core
run: ./gradlew build :preflight-core:preflight-gradle-plugin:publishPlugins :preflight-core:preflight-runtime:publishMavenPublicationToOrbitalRepository
env:
GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PUBLISH_KEY }}
GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PUBLISH_SECRET }}
Expand Down
43 changes: 23 additions & 20 deletions BUILDING.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
# Building and Releasing

## Building locally
## Project Structure

```bash
cd preflight-core
./gradlew build
```
The repository uses two separate Gradle builds connected via composite builds:

- **`preflight-spec/`** — Standalone build for the markdown test spec parser/writer. Has no Orbital dependencies (only commonmark + jackson), so Orbital itself can depend on it without circular dependencies.
- **`preflight-core/`** — Main build containing `preflight-runtime` and `preflight-gradle-plugin`. Depends on Orbital libraries. Consumes `preflight-spec` via composite build (`includeBuild`).

This builds all modules (`preflight-spec`, `preflight-runtime`, `preflight-gradle-plugin`) and runs their tests.
The root `settings.gradle.kts` wires both builds together along with the example projects.

To also run the example project tests:
## Building locally

```bash
# From the repo root
# Full build from repo root (builds everything including examples)
./gradlew build

# Build preflight-spec standalone
cd preflight-spec && ./gradlew build

# Build preflight-core (resolves preflight-spec via composite build)
cd preflight-core && ./gradlew build
```

## Installing to local Maven repo
Expand Down Expand Up @@ -51,16 +57,12 @@ The plugin itself injects the Orbital Maven repositories automatically, so no ot

## Bumping the version

The version is set in one place: `preflight-core/build.gradle.kts`
The version is set in **two places** (kept in sync manually):

```kotlin
allprojects {
group = "com.orbitalhq.preflight"
version = "0.1.0" // <-- change this
}
```
1. `preflight-core/build.gradle.kts` — `val PROJECT_VERSION = "0.1.0-SNAPSHOT"`
2. `preflight-spec/build.gradle.kts` — `version = "0.1.0-SNAPSHOT"`

All submodules inherit this version. The Gradle plugin also embeds it at build time via a generated `Versions.kt` constant.
All preflight-core submodules inherit their version from `preflight-core/build.gradle.kts`. The Gradle plugin also embeds it at build time via a generated `Versions.kt` constant.

## Releasing

Expand All @@ -71,7 +73,7 @@ Releases are triggered by pushing a git tag. GitHub Actions handles building, si
git checkout main
git pull

# 2. Bump the version in preflight-core/build.gradle.kts, commit
# 2. Bump the version in both build.gradle.kts files, commit

# 3. Tag the release
git tag v0.1.0
Expand All @@ -84,9 +86,10 @@ git push origin v0.1.0
The `release.yml` workflow then:
1. Builds the project with JDK 21
2. Signs artifacts with GPG
3. Publishes the Gradle plugin to the **Gradle Plugin Portal**
4. Publishes `preflight-runtime` and `preflight-spec` to the **Orbital Maven repository** (`s3://repo.orbitalhq.com/release`)
5. Creates a GitHub Release with JARs and auto-generated notes
3. Publishes `preflight-spec` to the **Orbital Maven repository**
4. Publishes the Gradle plugin to the **Gradle Plugin Portal**
5. Publishes `preflight-runtime` to the **Orbital Maven repository**
6. Creates a GitHub Release with JARs and auto-generated notes

## Where artifacts are published

Expand Down
18 changes: 15 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,28 @@ Preflight is a Kotlin-based testing framework for Taxi/Orbital projects. It prov

### Core Components

- **preflight-spec**: Standalone markdown test spec parser/writer (`preflight-spec/`)
- Has zero Orbital dependencies (only commonmark + jackson)
- Lives in its own top-level Gradle build so Orbital can depend on it without circular dependencies
- `TestSpecReader` / `TestSpecWriter`: Parse and generate markdown test specifications

- **preflight-runtime**: Core testing DSL and execution engine (`preflight-core/preflight-runtime/`)
- `OrbitalSpec`: Base test class extending Kotest's DescribeSpec with Taxi/Orbital-specific functionality
- `PreflightExtension`: Kotest extension that handles Taxi compilation and Orbital service initialization
- `StubHelper`: Utilities for stubbing external data sources in tests
- Environment variable support and configuration management
- Depends on `preflight-spec` via Maven coordinates (resolved by composite build locally)

- **preflight-gradle-plugin**: Gradle plugin for project integration (`preflight-core/preflight-gradle-plugin/`)
- `PreflightPlugin`: Main plugin class that configures Kotlin JVM, dependencies, and test execution
- Automatically sets up JVM toolchain (Java 21), source sets, and test runner configuration

### Project Structure

The repository uses a composite build structure:
- Root project includes core modules and example projects as composite builds
The repository uses a two-build composite structure:
- `preflight-spec/` — standalone Gradle build (no Orbital dependencies)
- `preflight-core/` — main Gradle build containing runtime and plugin (depends on Orbital)
- Root `settings.gradle.kts` wires both builds together with example projects via `includeBuild`
- Example projects demonstrate usage patterns and serve as integration tests
- Documentation site built with Next.js in `docs/` directory

Expand Down Expand Up @@ -119,4 +127,8 @@ preflight {

## Version Management

Project version is managed centrally in `preflight-core/build.gradle.kts` (currently 0.0.4). The Gradle plugin uses code generation to embed version constants at build time via the `generateVersionConstants` task.
Project version is set in two places (kept in sync manually):
- `preflight-core/build.gradle.kts` — `val PROJECT_VERSION = "0.1.0-SNAPSHOT"` (inherited by runtime and plugin)
- `preflight-spec/build.gradle.kts` — `version = "0.1.0-SNAPSHOT"`

The Gradle plugin uses code generation to embed version constants at build time via the `generateVersionConstants` task.
30 changes: 15 additions & 15 deletions example-projects/warehouse-orders/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,24 @@ plugins {

// OR specify a custom Orbital version
preflight {
orbitalVersion = "0.38.0-SNAPSHOT"
orbitalVersion = "0.38.0-M4"
}

repositories {
mavenLocal()
mavenCentral()
maven {
name = "orbital"
url = URI("https://repo.orbitalhq.com/release")
mavenContent {
releasesOnly()
}
}
maven {
name = "orbital-snapshot"
url = URI("https://repo.orbitalhq.com/snapshot")
mavenContent {
snapshotsOnly()
}
}
// maven {
// name = "orbital"
// url = URI("https://repo.orbitalhq.com/release")
// mavenContent {
// releasesOnly()
// }
// }
// maven {
// name = "orbital-snapshot"
// url = URI("https://repo.orbitalhq.com/snapshot")
// mavenContent {
// snapshotsOnly()
// }
// }
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ spec-version: 0.1

# Enrich warehouse order

This test covers streaming a warehouse order event and eniching it with a product name from an API
This test covers streaming a warehouse order event and enriching it with a product name from an API

## Query

Expand All @@ -24,31 +24,75 @@ stream { SurePostDeliveryEvent } as {
Message:
```json
{
"productId" : "PROD-1001",
"qtyDelivered" : 45,
"orderId" : "520c80f8-661e-48c7-8b4e-c9c36bd93785",
"productId" : "PROD-1013",
"qtyDelivered" : 72,
"orderId" : "a29788b5-6b7a-4c30-8e9c-775c1341fef8",
"supplierId" : "SUREPOST",
"timestamp" : "2026-02-26T05:54:25.719167197"
"timestamp" : "2026-02-27T08:21:37.136364734"
}
```

Message:
```json
{
"productId" : "PROD-1003",
"qtyDelivered" : 20,
"orderId" : "e69e51a4-85e6-4fe6-90a8-4faec726e316",
"supplierId" : "SUREPOST",
"timestamp" : "2026-02-27T08:21:39.136643659"
}
```

Message:
```json
{
"productId" : "PROD-1003",
"qtyDelivered" : 26,
"orderId" : "5e3ea02a-9eaf-45c9-ab66-9150d5aeb981",
"supplierId" : "SUREPOST",
"timestamp" : "2026-02-27T08:21:41.136906122"
}
```

### getProduct
<!-- operation: ProductsApi@@getProduct -->

Request:
```json
{
"productId" : "PROD-1013"
}
```

Response:
```json
{"productId":"PROD-1013","sku":"SKU-WEB013","productName":"HD Webcam with Microphone","category":"Electronics","storageLocation":"WAREHOUSE-A-02"}
```

### getProduct
<!-- operation: ProductsApi@@getProduct -->

Request:
```json
{
"productId" : "PROD-1003"
}
```

Response:
```json
{"productId":"PROD-1001","sku":"SKU-LAP001","productName":"Gaming Laptop Pro 15\"","category":"Electronics","storageLocation":"WAREHOUSE-A-02"}
{"productId":"PROD-1003","sku":"SKU-KEY003","productName":"Mechanical Keyboard RGB","category":"Accessories","storageLocation":"WAREHOUSE-B-01"}
```

## Expected Result

```json
{
"productName" : "Gaming Laptop Pro 15\"",
"productId" : "PROD-1001",
"qtyDelivered" : 45,
"orderId" : "520c80f8-661e-48c7-8b4e-c9c36bd93785",
"productName" : "HD Webcam with Microphone",
"productId" : "PROD-1013",
"qtyDelivered" : 72,
"orderId" : "a29788b5-6b7a-4c30-8e9c-775c1341fef8",
"supplierId" : "SUREPOST",
"timestamp" : "26-Feb-2026 05:54:25"
"timestamp" : "27-Feb-2026 08:21:37"
}
```
```
3 changes: 2 additions & 1 deletion preflight-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ plugins {
`maven-publish`
}

val PROJECT_VERSION = "0.1.0-SNAPSHOT"


tasks.register("publishAll") {
Expand All @@ -26,7 +27,7 @@ tasks.register("publishAllMavenLocal") {

allprojects {
group = "com.orbitalhq.preflight"
version = "0.1.0-M2"
version = PROJECT_VERSION

repositories {
mavenCentral()
Expand Down
1 change: 1 addition & 0 deletions preflight-core/preflight-gradle-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ tasks.shadowJar {
archiveClassifier.set("") // Make this the main JAR
dependencies {
include(project(":preflight-runtime"))
include(dependency("com.orbitalhq.preflight:preflight-spec"))
include(dependency("org.taxilang:.*"))
include(dependency("com.orbitalhq:.*"))
}
Expand Down
4 changes: 2 additions & 2 deletions preflight-core/preflight-runtime/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ plugins {
}

val taxiVersion = "1.71.0-SNAPSHOT"
val orbitalVersion = "0.38.0-SNAPSHOT" // Default version, can be overridden in consumer projects
val orbitalVersion = "0.38.0-M4" // Default version, can be overridden in consumer projects

dependencies {
implementation(project(":preflight-spec"))
implementation("com.orbitalhq.preflight:preflight-spec")
testImplementation(platform("org.junit:junit-bom:5.10.0"))
testImplementation("org.junit.jupiter:junit-jupiter")
implementation(platform("org.testcontainers:testcontainers-bom:1.19.3"))
Expand Down
Loading
Loading