From 380a0d985e0504cef5a1f0177ee97560772f3370 Mon Sep 17 00:00:00 2001 From: Nicklas Lundin Date: Fri, 24 Oct 2025 11:52:11 +0200 Subject: [PATCH 1/3] docs: document how build works --- BUILD.md | 222 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 2 + 2 files changed, 224 insertions(+) create mode 100644 BUILD.md diff --git a/BUILD.md b/BUILD.md new file mode 100644 index 00000000..5eb878ab --- /dev/null +++ b/BUILD.md @@ -0,0 +1,222 @@ +# Build Architecture + +This document describes the Docker multi-stage build architecture used in this repository. + +## Overview + +The Dockerfile uses a multi-stage build approach to: +- Compile Rust code for both native and WebAssembly targets +- Build and test OpenFeature providers (JavaScript and Java) +- Run integration tests with example hosts (Node.js, Java, Go, Python) +- Package artifacts for distribution + +## Build Stage Diagram + +The diagram below shows all build stages and their dependencies: + +```mermaid +flowchart TD + %% Base images + alpine[alpine:3.22] + node[node:20-alpine] + java[eclipse-temurin:21-alpine] + go[golang:1.23-alpine] + python[python:3.11-slim] + temurin17[eclipse-temurin:17-jdk] + + %% Base stages + alpine --> rust-base[rust-base
Rust toolchain + protoc] + node --> openfeature-provider-js-base[openfeature-provider-js-base
Node deps + proto gen] + node --> node-host-base[node-host-base
Example host] + java --> java-host-base[java-host-base
Example host] + go --> go-host-base[go-host-base
Example host] + python --> python-host-base[python-host-base
Example host] + temurin17 --> openfeature-provider-java-base[openfeature-provider-java-base
Java provider base] + + %% Dependency compilation + rust-base --> rust-deps[rust-deps
Cached Rust dependencies] + rust-deps --> wasm-deps[wasm-deps
WASM-specific deps] + + %% Test stages for native Rust + rust-deps --> confidence-resolver.test[confidence-resolver.test
✓ Core resolver tests] + rust-deps --> wasm-msg.test[wasm-msg.test
✓ WASM msg tests] + + %% Lint stages for native Rust + rust-deps --> confidence-resolver.lint[confidence-resolver.lint
⚡ Core resolver lint] + rust-deps --> wasm-msg.lint[wasm-msg.lint
⚡ WASM msg lint] + + %% WASM build and lint + wasm-deps --> wasm-rust-guest.build[wasm-rust-guest.build
🔨 Build WASM resolver] + wasm-deps --> wasm-rust-guest.lint[wasm-rust-guest.lint
⚡ WASM guest lint] + wasm-deps --> confidence-cloudflare-resolver.lint[confidence-cloudflare-resolver.lint
⚡ Cloudflare lint] + + %% WASM artifact + wasm-rust-guest.build --> wasm-rust-guest.artifact[wasm-rust-guest.artifact
📦 confidence_resolver.wasm] + + %% Host integration tests + node-host-base --> node-host.test[node-host.test
✓ Node host integration] + java-host-base --> java-host.test[java-host.test
✓ Java host integration] + go-host-base --> go-host.test[go-host.test
✓ Go host integration] + python-host-base --> python-host.test[python-host.test
✓ Python host integration] + wasm-rust-guest.artifact -.-> node-host.test + wasm-rust-guest.artifact -.-> java-host.test + wasm-rust-guest.artifact -.-> go-host.test + wasm-rust-guest.artifact -.-> python-host.test + + %% OpenFeature JS provider + openfeature-provider-js-base --> openfeature-provider-js.build[openfeature-provider-js.build
🔨 TypeScript build] + wasm-rust-guest.artifact -.-> openfeature-provider-js-base + openfeature-provider-js-base --> openfeature-provider-js.test[openfeature-provider-js.test
✓ Provider tests] + openfeature-provider-js.test --> openfeature-provider-js.test_e2e[openfeature-provider-js.test_e2e
✓ E2E tests] + openfeature-provider-js.build --> openfeature-provider-js.pack[openfeature-provider-js.pack
📦 npm pack] + openfeature-provider-js.pack --> openfeature-provider-js.artifact[openfeature-provider-js.artifact
📦 package.tgz] + + %% OpenFeature Java provider + openfeature-provider-java-base --> openfeature-provider-java.test[openfeature-provider-java.test
✓ Java provider tests] + openfeature-provider-java-base --> openfeature-provider-java.build[openfeature-provider-java.build
🔨 Maven build] + openfeature-provider-java.build --> openfeature-provider-java.publish[openfeature-provider-java.publish
🚀 Maven Central] + wasm-rust-guest.artifact -.-> openfeature-provider-java-base + + %% All stage aggregates everything + wasm-rust-guest.artifact --> all[all
✅ Complete build] + confidence-resolver.test --> all + wasm-msg.test --> all + openfeature-provider-js.test --> all + openfeature-provider-js.test_e2e --> all + openfeature-provider-java.test --> all + node-host.test --> all + java-host.test --> all + go-host.test --> all + python-host.test --> all + confidence-resolver.lint --> all + wasm-msg.lint --> all + wasm-rust-guest.lint --> all + confidence-cloudflare-resolver.lint --> all + openfeature-provider-js.build --> all + openfeature-provider-java.build --> all + + %% Styling + classDef baseImage fill:#e1f5ff,stroke:#0066cc + classDef buildStage fill:#fff4e1,stroke:#ff8c00 + classDef testStage fill:#e8f5e9,stroke:#2e7d32 + classDef lintStage fill:#fff3e0,stroke:#f57c00 + classDef artifact fill:#f3e5f5,stroke:#7b1fa2 + classDef publish fill:#ffebee,stroke:#c62828 + classDef final fill:#c8e6c9,stroke:#388e3c + + class alpine,node,java,go,python,temurin17 baseImage + class rust-base,openfeature-provider-js-base,node-host-base,java-host-base,go-host-base,python-host-base,openfeature-provider-java-base,rust-deps,wasm-deps baseImage + class wasm-rust-guest.build,openfeature-provider-js.build,openfeature-provider-java.build buildStage + class confidence-resolver.test,wasm-msg.test,node-host.test,java-host.test,go-host.test,python-host.test,openfeature-provider-js.test,openfeature-provider-js.test_e2e,openfeature-provider-java.test testStage + class confidence-resolver.lint,wasm-msg.lint,wasm-rust-guest.lint,confidence-cloudflare-resolver.lint lintStage + class wasm-rust-guest.artifact,openfeature-provider-js.pack,openfeature-provider-js.artifact artifact + class openfeature-provider-java.publish publish + class all final +``` + +**Legend:** +- 🔨 Build stages compile code +- ✓ Test stages run unit/integration tests +- ⚡ Lint stages run code quality checks +- 📦 Artifact stages extract build outputs +- 🚀 Publish stages deploy to registries +- ✅ Final `all` stage aggregates everything + +## Key Features + +### Dependency Caching +Rust dependencies are compiled once in the `rust-deps` stage and reused across all subsequent builds. This significantly speeds up incremental builds. + +### Parallel Execution +Test and lint stages are independent and can run concurrently, reducing total build time. + +### WASM Artifact Sharing +The core `confidence_resolver.wasm` is built once in `wasm-rust-guest.build` and shared across: +- All host examples (Node.js, Java, Go, Python) +- OpenFeature JavaScript provider +- OpenFeature Java provider + +### Targeted Builds +You can build specific components using Docker's `--target` flag: + +```bash +# Build only the WASM artifact +docker build --target=wasm-rust-guest.artifact . + +# Build and extract the npm package +docker build --target=openfeature-provider-js.artifact . + +# Run only JavaScript provider tests +docker build --target=openfeature-provider-js.test . + +# Build everything (default) +docker build . +``` + +## Stage Descriptions + +### Base Stages + +- **rust-base**: Installs Rust toolchain, protoc, and build dependencies +- **openfeature-provider-js-base**: Node.js environment with dependencies and proto generation +- **node-host-base**, **java-host-base**, **go-host-base**, **python-host-base**: Example host environments +- **openfeature-provider-java-base**: Java provider environment with Maven + +### Dependency Stages + +- **rust-deps**: Compiles all Rust dependencies (cached layer) +- **wasm-deps**: Extends rust-deps with WASM-specific dependencies + +### Build Stages + +- **wasm-rust-guest.build**: Compiles Rust resolver to WebAssembly +- **openfeature-provider-js.build**: Compiles TypeScript to JavaScript +- **openfeature-provider-java.build**: Builds Java provider with Maven + +### Test Stages + +- **confidence-resolver.test**: Unit tests for core resolver +- **wasm-msg.test**: Tests for WASM messaging layer +- **openfeature-provider-js.test**: Unit tests for JavaScript provider +- **openfeature-provider-js.test_e2e**: End-to-end tests (requires credentials) +- **openfeature-provider-java.test**: Tests for Java provider +- **node-host.test**, **java-host.test**, **go-host.test**, **python-host.test**: Integration tests + +### Lint Stages + +- **confidence-resolver.lint**: Clippy checks for core resolver +- **wasm-msg.lint**: Clippy checks for WASM messaging +- **wasm-rust-guest.lint**: Clippy checks for WASM guest +- **confidence-cloudflare-resolver.lint**: Clippy checks for Cloudflare resolver + +### Artifact Stages + +- **wasm-rust-guest.artifact**: Extracts `confidence_resolver.wasm` +- **openfeature-provider-js.pack**: Creates npm package tarball +- **openfeature-provider-js.artifact**: Extracts package.tgz for distribution + +### Publish Stages + +- **openfeature-provider-java.publish**: Publishes Java provider to Maven Central (requires secrets) + +### Aggregation Stage + +- **all**: Default stage that ensures all tests, lints, and builds complete successfully + +## CI/CD Integration + +The build stages are used in GitHub Actions workflows: + +- **release-please.yml**: Publishes packages when releases are created + - Uses `openfeature-provider-js.artifact` to extract npm package + - Uses `openfeature-provider-java.publish` to deploy to Maven Central + +## Docker Build Cache + +The repository uses Docker layer caching to speed up builds in CI: + +```yaml +cache-from: type=registry,ref=ghcr.io/${{ github.repository }}/cache:main +``` + +This allows GitHub Actions to reuse layers from previous builds. diff --git a/README.md b/README.md index 97dc9b56..0a387a75 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,8 @@ make run-go make run-python ``` +See [BUILD.md](BUILD.md) for detailed information about the Docker multi-stage build architecture. + ## Running the example hosts There are host implementations for different languages in the `wasm` folder. From 7cd5374aae125f1724f14c49e429640b506b97c6 Mon Sep 17 00:00:00 2001 From: Nicklas Lundin Date: Fri, 24 Oct 2025 11:59:15 +0200 Subject: [PATCH 2/3] build: remove host examples from dockerfile --- Dockerfile | 165 ----------------------------------------------------- 1 file changed, 165 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4ac12d10..56b17317 100644 --- a/Dockerfile +++ b/Dockerfile @@ -198,165 +198,6 @@ FROM wasm-deps AS confidence-cloudflare-resolver.lint WORKDIR /workspace/confidence-cloudflare-resolver RUN make lint -# ============================================================================== -# Node.js Host - Run Node.js host example -# ============================================================================== -FROM node:20-alpine AS node-host-base - -# Install protoc for proto generation -RUN apk add --no-cache protobuf-dev protoc make - -WORKDIR /app - -# Enable Corepack for Yarn -RUN corepack enable - -# Copy package files for dependency caching -COPY wasm/node-host/package.json wasm/node-host/yarn.lock wasm/node-host/.yarnrc.yml ./ -COPY wasm/node-host/Makefile ./ - -# Copy proto files for generation -COPY wasm/proto ../proto/ - -# Build using Makefile (installs deps + generates protos) -ENV IN_DOCKER_BUILD=1 -RUN make build - -# Copy source code -COPY wasm/node-host/src ./src/ -COPY wasm/node-host/tsconfig.json ./ - -# Copy WASM module from wasm-rust-guest.artifact -COPY --from=wasm-rust-guest.artifact /confidence_resolver.wasm ../confidence_resolver.wasm - -# Copy resolver state -COPY wasm/resolver_state.pb ../resolver_state.pb - -# ============================================================================== -# Test Node.js Host (integration test) -# ============================================================================== -FROM node-host-base AS node-host.test -RUN make run - -# ============================================================================== -# Java Host - Run Java host example -# ============================================================================== -FROM eclipse-temurin:21-alpine AS java-host-base - -# Install Maven and protobuf -RUN apk add --no-cache maven protobuf-dev protoc make - -WORKDIR /app - -# Copy pom.xml for dependency caching -COPY wasm/java-host/pom.xml ./ -COPY wasm/java-host/Makefile ./ - -# Download dependencies (this layer will be cached) -RUN mvn dependency:go-offline -q || true - -# Copy proto files -COPY wasm/proto ../proto/ - -# Copy source code -COPY wasm/java-host/src ./src/ - -# Build using Makefile (compiles proto + builds JAR) -ENV IN_DOCKER_BUILD=1 -RUN make build - -# Copy WASM module from wasm-rust-guest.artifact -COPY --from=wasm-rust-guest.artifact /confidence_resolver.wasm ../confidence_resolver.wasm - -# Copy resolver state -COPY wasm/resolver_state.pb ../resolver_state.pb - -# ============================================================================== -# Test Java Host (integration test) -# ============================================================================== -FROM java-host-base AS java-host.test -RUN make run - -# ============================================================================== -# Go Host - Run Go host example -# ============================================================================== -FROM golang:1.23-alpine AS go-host-base - -# Install protobuf and protoc-gen-go -RUN apk add --no-cache protobuf-dev protoc bash make git - -WORKDIR /app - -# Copy go.mod for dependency caching -COPY wasm/go-host/go.mod wasm/go-host/go.sum ./ -COPY wasm/go-host/Makefile ./ - -# Download Go dependencies (this layer will be cached) -RUN go mod download - -# Install protoc-gen-go (pin version for stability) -RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.34 - -# Copy proto files -COPY wasm/proto ../proto/ - -# Copy source code -COPY wasm/go-host/*.go wasm/go-host/*.sh ./ - -# Build using Makefile (generates proto + builds) -ENV IN_DOCKER_BUILD=1 -RUN make build - -# Copy WASM module -COPY --from=wasm-rust-guest.artifact /confidence_resolver.wasm ../confidence_resolver.wasm - -# Copy resolver state -COPY wasm/resolver_state.pb ../resolver_state.pb - -# ============================================================================== -# Test Go Host (integration test) -# ============================================================================== -FROM go-host-base AS go-host.test -RUN make run - -# ============================================================================== -# Python Host - Run Python host example -# ============================================================================== -FROM python:3.11-slim AS python-host-base - -# Install protobuf and dependencies (libprotobuf-dev includes google proto files) -RUN apt-get update && \ - apt-get install -y --no-install-recommends protobuf-compiler libprotobuf-dev make && \ - rm -rf /var/lib/apt/lists/* - -WORKDIR /app - -# Copy Makefile and proto generation script -COPY wasm/python-host/Makefile ./ -COPY wasm/python-host/generate_proto.py ./ - -# Copy proto files -COPY wasm/proto ../proto/ - -# Build using Makefile (creates venv + installs deps + generates proto) -ENV IN_DOCKER_BUILD=1 -RUN make build - -# Copy source code -COPY wasm/python-host/*.py ./ - -# Copy WASM module -COPY --from=wasm-rust-guest.artifact /confidence_resolver.wasm ../confidence_resolver.wasm - -# Copy resolver state -COPY wasm/resolver_state.pb ../resolver_state.pb - -# ============================================================================== -# Test Python Host (integration test) -# ============================================================================== -FROM python-host-base AS python-host.test -RUN make run - # ============================================================================== # OpenFeature Provider (TypeScript) - Build and test # ============================================================================== @@ -514,12 +355,6 @@ COPY --from=openfeature-provider-js.test /app/package.json /markers/test-openfea COPY --from=openfeature-provider-js.test_e2e /app/package.json /markers/test-openfeature-js-e2e COPY --from=openfeature-provider-java.test /app/pom.xml /markers/test-openfeature-java -# Force integration test stages to run (host examples) -COPY --from=node-host.test /app/package.json /markers/integration-node -COPY --from=java-host.test /app/pom.xml /markers/integration-java -COPY --from=go-host.test /app/go.mod /markers/integration-go -COPY --from=python-host.test /app/Makefile /markers/integration-python - # Force lint stages to run by copying marker files COPY --from=confidence-resolver.lint /workspace/Cargo.toml /markers/lint-resolver COPY --from=wasm-msg.lint /workspace/Cargo.toml /markers/lint-wasm-msg From 9e58d702ed4ea68bce2907707bc1be22c0282f87 Mon Sep 17 00:00:00 2001 From: Nicklas Lundin Date: Fri, 24 Oct 2025 12:52:01 +0200 Subject: [PATCH 3/3] docs: update build doc --- BUILD.md | 132 +++++++++++++++++++++++++------------------------------ 1 file changed, 59 insertions(+), 73 deletions(-) diff --git a/BUILD.md b/BUILD.md index 5eb878ab..ed2bd676 100644 --- a/BUILD.md +++ b/BUILD.md @@ -7,7 +7,6 @@ This document describes the Docker multi-stage build architecture used in this r The Dockerfile uses a multi-stage build approach to: - Compile Rust code for both native and WebAssembly targets - Build and test OpenFeature providers (JavaScript and Java) -- Run integration tests with example hosts (Node.js, Java, Go, Python) - Package artifacts for distribution ## Build Stage Diagram @@ -19,31 +18,27 @@ flowchart TD %% Base images alpine[alpine:3.22] node[node:20-alpine] - java[eclipse-temurin:21-alpine] - go[golang:1.23-alpine] - python[python:3.11-slim] - temurin17[eclipse-temurin:17-jdk] + java[eclipse-temurin:17-jdk] - %% Base stages + %% Rust toolchain and dependency stages alpine --> rust-base[rust-base
Rust toolchain + protoc] - node --> openfeature-provider-js-base[openfeature-provider-js-base
Node deps + proto gen] - node --> node-host-base[node-host-base
Example host] - java --> java-host-base[java-host-base
Example host] - go --> go-host-base[go-host-base
Example host] - python --> python-host-base[python-host-base
Example host] - temurin17 --> openfeature-provider-java-base[openfeature-provider-java-base
Java provider base] - - %% Dependency compilation rust-base --> rust-deps[rust-deps
Cached Rust dependencies] - rust-deps --> wasm-deps[wasm-deps
WASM-specific deps] - %% Test stages for native Rust - rust-deps --> confidence-resolver.test[confidence-resolver.test
✓ Core resolver tests] - rust-deps --> wasm-msg.test[wasm-msg.test
✓ WASM msg tests] + %% Native test/lint base + rust-base --> rust-test-base[rust-test-base
Base for native tests/lints] + rust-deps -.->|copies cargo cache| rust-test-base + + %% WASM build base + rust-base --> wasm-deps[wasm-deps
WASM build environment] + rust-deps -.->|copies cargo cache| wasm-deps - %% Lint stages for native Rust - rust-deps --> confidence-resolver.lint[confidence-resolver.lint
⚡ Core resolver lint] - rust-deps --> wasm-msg.lint[wasm-msg.lint
⚡ WASM msg lint] + %% Native Rust tests + rust-test-base --> confidence-resolver.test[confidence-resolver.test
✓ Core resolver tests] + rust-test-base --> wasm-msg.test[wasm-msg.test
✓ WASM msg tests] + + %% Native Rust lints + rust-test-base --> confidence-resolver.lint[confidence-resolver.lint
⚡ Core resolver lint] + rust-test-base --> wasm-msg.lint[wasm-msg.lint
⚡ WASM msg lint] %% WASM build and lint wasm-deps --> wasm-rust-guest.build[wasm-rust-guest.build
🔨 Build WASM resolver] @@ -53,29 +48,21 @@ flowchart TD %% WASM artifact wasm-rust-guest.build --> wasm-rust-guest.artifact[wasm-rust-guest.artifact
📦 confidence_resolver.wasm] - %% Host integration tests - node-host-base --> node-host.test[node-host.test
✓ Node host integration] - java-host-base --> java-host.test[java-host.test
✓ Java host integration] - go-host-base --> go-host.test[go-host.test
✓ Go host integration] - python-host-base --> python-host.test[python-host.test
✓ Python host integration] - wasm-rust-guest.artifact -.-> node-host.test - wasm-rust-guest.artifact -.-> java-host.test - wasm-rust-guest.artifact -.-> go-host.test - wasm-rust-guest.artifact -.-> python-host.test - %% OpenFeature JS provider - openfeature-provider-js-base --> openfeature-provider-js.build[openfeature-provider-js.build
🔨 TypeScript build] - wasm-rust-guest.artifact -.-> openfeature-provider-js-base + node --> openfeature-provider-js-base[openfeature-provider-js-base
Node deps + proto gen] + wasm-rust-guest.artifact -.->|copies WASM| openfeature-provider-js-base openfeature-provider-js-base --> openfeature-provider-js.test[openfeature-provider-js.test
✓ Provider tests] openfeature-provider-js.test --> openfeature-provider-js.test_e2e[openfeature-provider-js.test_e2e
✓ E2E tests] - openfeature-provider-js.build --> openfeature-provider-js.pack[openfeature-provider-js.pack
📦 npm pack] + openfeature-provider-js-base --> openfeature-provider-js.build[openfeature-provider-js.build
🔨 TypeScript build] + openfeature-provider-js.build --> openfeature-provider-js.pack[openfeature-provider-js.pack
📦 yarn pack] openfeature-provider-js.pack --> openfeature-provider-js.artifact[openfeature-provider-js.artifact
📦 package.tgz] %% OpenFeature Java provider + java --> openfeature-provider-java-base[openfeature-provider-java-base
Maven + proto gen] + wasm-rust-guest.artifact -.->|copies WASM| openfeature-provider-java-base openfeature-provider-java-base --> openfeature-provider-java.test[openfeature-provider-java.test
✓ Java provider tests] openfeature-provider-java-base --> openfeature-provider-java.build[openfeature-provider-java.build
🔨 Maven build] openfeature-provider-java.build --> openfeature-provider-java.publish[openfeature-provider-java.publish
🚀 Maven Central] - wasm-rust-guest.artifact -.-> openfeature-provider-java-base %% All stage aggregates everything wasm-rust-guest.artifact --> all[all
✅ Complete build] @@ -84,10 +71,6 @@ flowchart TD openfeature-provider-js.test --> all openfeature-provider-js.test_e2e --> all openfeature-provider-java.test --> all - node-host.test --> all - java-host.test --> all - go-host.test --> all - python-host.test --> all confidence-resolver.lint --> all wasm-msg.lint --> all wasm-rust-guest.lint --> all @@ -104,10 +87,10 @@ flowchart TD classDef publish fill:#ffebee,stroke:#c62828 classDef final fill:#c8e6c9,stroke:#388e3c - class alpine,node,java,go,python,temurin17 baseImage - class rust-base,openfeature-provider-js-base,node-host-base,java-host-base,go-host-base,python-host-base,openfeature-provider-java-base,rust-deps,wasm-deps baseImage + class alpine,node,java baseImage + class rust-base,rust-deps,rust-test-base,wasm-deps,openfeature-provider-js-base,openfeature-provider-java-base baseImage class wasm-rust-guest.build,openfeature-provider-js.build,openfeature-provider-java.build buildStage - class confidence-resolver.test,wasm-msg.test,node-host.test,java-host.test,go-host.test,python-host.test,openfeature-provider-js.test,openfeature-provider-js.test_e2e,openfeature-provider-java.test testStage + class confidence-resolver.test,wasm-msg.test,openfeature-provider-js.test,openfeature-provider-js.test_e2e,openfeature-provider-java.test testStage class confidence-resolver.lint,wasm-msg.lint,wasm-rust-guest.lint,confidence-cloudflare-resolver.lint lintStage class wasm-rust-guest.artifact,openfeature-provider-js.pack,openfeature-provider-js.artifact artifact class openfeature-provider-java.publish publish @@ -132,7 +115,6 @@ Test and lint stages are independent and can run concurrently, reducing total bu ### WASM Artifact Sharing The core `confidence_resolver.wasm` is built once in `wasm-rust-guest.build` and shared across: -- All host examples (Node.js, Java, Go, Python) - OpenFeature JavaScript provider - OpenFeature Java provider @@ -157,51 +139,47 @@ docker build . ### Base Stages -- **rust-base**: Installs Rust toolchain, protoc, and build dependencies -- **openfeature-provider-js-base**: Node.js environment with dependencies and proto generation -- **node-host-base**, **java-host-base**, **go-host-base**, **python-host-base**: Example host environments -- **openfeature-provider-java-base**: Java provider environment with Maven - -### Dependency Stages - -- **rust-deps**: Compiles all Rust dependencies (cached layer) -- **wasm-deps**: Extends rust-deps with WASM-specific dependencies - -### Build Stages - -- **wasm-rust-guest.build**: Compiles Rust resolver to WebAssembly -- **openfeature-provider-js.build**: Compiles TypeScript to JavaScript -- **openfeature-provider-java.build**: Builds Java provider with Maven +- **rust-base** (FROM alpine:3.22): Installs Rust toolchain via rustup, protoc, and build dependencies +- **rust-deps** (FROM rust-base): Compiles all Rust workspace dependencies (cached layer for faster rebuilds) +- **rust-test-base** (FROM rust-base): Copies dependency cache and source code for native testing/linting +- **wasm-deps** (FROM rust-base): Copies dependency cache and source code for WASM builds +- **openfeature-provider-js-base** (FROM node:20-alpine): Node.js environment with Yarn, dependencies, and proto generation +- **openfeature-provider-java-base** (FROM eclipse-temurin:17-jdk): Java environment with Maven and proto files ### Test Stages -- **confidence-resolver.test**: Unit tests for core resolver -- **wasm-msg.test**: Tests for WASM messaging layer -- **openfeature-provider-js.test**: Unit tests for JavaScript provider -- **openfeature-provider-js.test_e2e**: End-to-end tests (requires credentials) -- **openfeature-provider-java.test**: Tests for Java provider -- **node-host.test**, **java-host.test**, **go-host.test**, **python-host.test**: Integration tests +- **confidence-resolver.test** (FROM rust-test-base): Unit tests for core resolver +- **wasm-msg.test** (FROM rust-test-base): Tests for WASM messaging layer +- **openfeature-provider-js.test** (FROM openfeature-provider-js-base): Unit tests for JavaScript provider +- **openfeature-provider-js.test_e2e** (FROM openfeature-provider-js.test): End-to-end tests (requires credentials via Docker secret) +- **openfeature-provider-java.test** (FROM openfeature-provider-java-base): Tests for Java provider ### Lint Stages -- **confidence-resolver.lint**: Clippy checks for core resolver -- **wasm-msg.lint**: Clippy checks for WASM messaging -- **wasm-rust-guest.lint**: Clippy checks for WASM guest -- **confidence-cloudflare-resolver.lint**: Clippy checks for Cloudflare resolver +- **confidence-resolver.lint** (FROM rust-test-base): Clippy checks for core resolver +- **wasm-msg.lint** (FROM rust-test-base): Clippy checks for WASM messaging +- **wasm-rust-guest.lint** (FROM wasm-deps): Clippy checks for WASM guest +- **confidence-cloudflare-resolver.lint** (FROM wasm-deps): Clippy checks for Cloudflare resolver + +### Build Stages + +- **wasm-rust-guest.build** (FROM wasm-deps): Compiles Rust resolver to WebAssembly (wasm32-unknown-unknown target) +- **openfeature-provider-js.build** (FROM openfeature-provider-js-base): Compiles TypeScript to JavaScript +- **openfeature-provider-java.build** (FROM openfeature-provider-java-base): Builds Java provider with Maven ### Artifact Stages -- **wasm-rust-guest.artifact**: Extracts `confidence_resolver.wasm` -- **openfeature-provider-js.pack**: Creates npm package tarball -- **openfeature-provider-js.artifact**: Extracts package.tgz for distribution +- **wasm-rust-guest.artifact** (FROM scratch): Extracts `confidence_resolver.wasm` (rust_guest.wasm → confidence_resolver.wasm) +- **openfeature-provider-js.pack** (FROM openfeature-provider-js.build): Creates npm package tarball via `yarn pack` +- **openfeature-provider-js.artifact** (FROM scratch): Extracts package.tgz for distribution ### Publish Stages -- **openfeature-provider-java.publish**: Publishes Java provider to Maven Central (requires secrets) +- **openfeature-provider-java.publish** (FROM openfeature-provider-java.build): Publishes Java provider to Maven Central (requires GPG and Maven secrets) ### Aggregation Stage -- **all**: Default stage that ensures all tests, lints, and builds complete successfully +- **all** (FROM scratch): Default stage that ensures all tests, lints, and builds complete successfully by copying marker files ## CI/CD Integration @@ -220,3 +198,11 @@ cache-from: type=registry,ref=ghcr.io/${{ github.repository }}/cache:main ``` This allows GitHub Actions to reuse layers from previous builds. + +## Dependency Flow + +The `rust-deps` stage builds dummy source files to compile all workspace dependencies, creating a cached layer. This cache is then copied into: +- `rust-test-base` (for native tests and lints) +- `wasm-deps` (for WASM builds) + +This approach ensures dependencies are only compiled once, even when building multiple targets.