Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
2b711dd
docs: design spec for edgezero #269 (extensible CLI) adaptation, base…
aram356 Jun 14, 2026
3e6441f
docs: fold R5 review into spec body (anyhow, spin runtime-config, fix…
aram356 Jun 16, 2026
b89efd3
docs: implementation plan for edgezero #269 adaptation; ignore superp…
aram356 Jun 16, 2026
63986d8
docs: correct plan Task 0 (dist is gitignored, not tracked)
aram356 Jun 16, 2026
d5bb70a
docs: apply prettier formatting to spec and plan
aram356 Jun 16, 2026
3b1c5ca
docs: address PR #110 review (registry-backed cpm test, non-default C…
aram356 Jun 16, 2026
4f5e814
docs: address PR #110 review round 2 (eslint .temp ignore, async_trai…
aram356 Jun 16, 2026
e546a82
docs: PR #110 review nits (docker commit msg, actionlint over PyYAML)
aram356 Jun 16, 2026
f84db7a
docs: exclude superpowers + vitepress build temp from prettier/eslint…
aram356 Jun 16, 2026
4f1a9dd
build: pin edgezero deps to feature/extensible-cli, bump spin-sdk to …
aram356 Jun 16, 2026
8e7aaac
feat: drop run_app manifest arg for axum/cloudflare/fastly (edgezero …
aram356 Jun 16, 2026
d38790b
feat: migrate spin adapter to spin-sdk 6 / wasm32-wasip2 (edgezero #269)
aram356 Jun 16, 2026
63e7fdd
feat: declare [stores.config] + spin wasip2/runtime-config in manifest
aram356 Jun 16, 2026
a35f769
feat: add MocktioneerConfig typed config (bid_cpm, validated)
aram356 Jun 16, 2026
77016f9
feat: resolve bid_cpm from config store at runtime (OpenRTB + APS), d…
aram356 Jun 16, 2026
bd26219
feat: add mocktioneer.toml typed config (bid_cpm default 0.20)
aram356 Jun 16, 2026
14fa94b
feat: add mocktioneer-cli with typed config validate/push
aram356 Jun 16, 2026
86e7315
build: copy missing adapter manifests before cargo fetch in Docker
aram356 Jun 16, 2026
b8733e0
chore: gitignore .edgezero/ (local config/kv state)
aram356 Jun 16, 2026
6cf54f9
docs: spin wasip2, bid_cpm-default pricing, edgezero-cli vs mocktione…
aram356 Jun 16, 2026
ea5d996
ci: spin wasip2 matrix + typed config validate/seed gate
aram356 Jun 16, 2026
a3c2634
feat: drop 'new' subcommand from mocktioneer-cli (nonsensical for a p…
aram356 Jun 16, 2026
697d7e3
test: use FastlyService/CloudflareService::dispatch in contract tests…
aram356 Jun 16, 2026
b039c7e
Formatting
aram356 Jun 16, 2026
478c3a3
docs+ci: quote GITHUB_OUTPUT (actionlint), document stores.config/spi…
aram356 Jun 16, 2026
24fc4a8
docs+ci: match config.md commands to manifest, quote GITHUB_OUTPUT re…
aram356 Jun 17, 2026
f092aff
docs: show in-repo mocktioneer-cli alongside edgezero-cli in run exam…
aram356 Jun 17, 2026
7cf8498
feat: sync to edgezero 89f59266 — blob app-config (AppConfig extracto…
aram356 Jun 23, 2026
c2a8ec4
docs: align spec/plan/guides to R8 blob fail-loud model; add config-p…
aram356 Jun 23, 2026
15ae460
fix(docker): seed default config blob into image so OpenRTB/APS serve…
aram356 Jun 26, 2026
92b21c3
refactor: validate bid_cpm with range(exclusive_min) instead of custo…
aram356 Jun 26, 2026
30025d2
docs: config-push prerequisite across API/integration/adapter pages; …
aram356 Jul 2, 2026
48473b3
Updated config files
aram356 Jul 2, 2026
e7dc0db
docs: bump eslint 9->10, @types/node 24->26, typescript-eslint (docs …
aram356 Jul 2, 2026
e79b00f
feat: mount framework introspection routes (/_mocktioneer/{manifest,c…
aram356 Jul 2, 2026
ae1689e
Formatting
aram356 Jul 2, 2026
4c03911
build: update edgezero introspection-routes pin to e68df70b
aram356 Jul 2, 2026
3b4f762
Use latest from edgzero branch
aram356 Jul 2, 2026
6f38760
fix: PR #110 review — Docker binds 0.0.0.0 (+ smoke), config-validate…
aram356 Jul 7, 2026
072237e
fix: pin runtime base to debian:bookworm-slim to match builder release
aram356 Jul 7, 2026
699b061
build: pin edgezero deps to released tag v0.0.4
aram356 Jul 9, 2026
0bd3e15
fix: PR #110 review round 3 — Dockerfile layer-cache, spin deploy fla…
aram356 Jul 9, 2026
889fba0
fix: PR #110 review round 4 — gate Docker push on smoke test, assert …
aram356 Jul 11, 2026
079d28a
test: exercise config-seeded auction through Fastly and Cloudflare ad…
aram356 Jul 11, 2026
04235ff
docs: document remote Fastly config-store setup (provision -> push ->…
aram356 Jul 13, 2026
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
1 change: 1 addition & 0 deletions .cargo/config.toml.local
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ git-fetch-with-cli = true
edgezero-adapter-axum = { path = "../edgezero/crates/edgezero-adapter-axum" }
edgezero-adapter-cloudflare = { path = "../edgezero/crates/edgezero-adapter-cloudflare" }
edgezero-adapter-fastly = { path = "../edgezero/crates/edgezero-adapter-fastly" }
edgezero-adapter-spin = { path = "../edgezero/crates/edgezero-adapter-spin" }
edgezero-cli = { path = "../edgezero/crates/edgezero-cli" }
edgezero-core = { path = "../edgezero/crates/edgezero-core" }
edgezero-macros = { path = "../edgezero/crates/edgezero-macros" }
1 change: 1 addition & 0 deletions .claude/agents/build-validator.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ cargo build --workspace --all-targets --all-features
```
cargo build -p mocktioneer-adapter-fastly --features fastly --target wasm32-wasip1
cargo build -p mocktioneer-adapter-cloudflare --features cloudflare --target wasm32-unknown-unknown
cargo build --release -p mocktioneer-adapter-spin --features spin --target wasm32-wasip2
```

## Feature matrix
Expand Down
1 change: 1 addition & 0 deletions .claude/agents/verify-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Zero warnings required. Report any clippy lints or format violations.
```
cargo build -p mocktioneer-adapter-fastly --features fastly --target wasm32-wasip1
cargo build -p mocktioneer-adapter-cloudflare --features cloudflare --target wasm32-unknown-unknown
cargo build --release -p mocktioneer-adapter-spin --features spin --target wasm32-wasip2
```

Both WASM targets must compile. Report any errors with the exact compiler output.
Expand Down
1 change: 1 addition & 0 deletions .claude/commands/check-ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ Run the full CI gate checks locally before pushing. Run all commands sequentiall
2. `cargo clippy --workspace --all-targets --all-features -- -D warnings`
3. `cargo test --workspace --all-targets`
4. `cargo check --workspace --all-targets --features "fastly cloudflare"`
5. `cargo run -p mocktioneer-cli -- config validate --strict --app-config mocktioneer.toml.example` (`mocktioneer.toml` is gitignored; validate the committed template)

If any step fails, show the errors and suggest fixes. Do not proceed to the next step until the current one passes.
4 changes: 2 additions & 2 deletions .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ jobs:
id: node-version
run: |
if [ -f .tool-versions ]; then
echo "node-version=$(grep '^nodejs ' .tool-versions | awk '{print $2}')" >> $GITHUB_OUTPUT
echo "node-version=$(grep '^nodejs ' .tool-versions | awk '{print $2}')" >> "$GITHUB_OUTPUT"
else
echo "node-version=20" >> $GITHUB_OUTPUT
echo "node-version=20" >> "$GITHUB_OUTPUT"
fi
- name: Setup Node.js
Expand Down
44 changes: 40 additions & 4 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ jobs:

- name: Get Rust version from .tool-versions
id: rust
run: echo "version=$(grep '^rust' .tool-versions | awk '{print $2}')" >> $GITHUB_OUTPUT
run: echo "version=$(grep '^rust' .tool-versions | awk '{print $2}')" >> "$GITHUB_OUTPUT"

- name: Get short SHA
id: sha
run: echo "short=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT
run: echo "short=${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"

- name: Log in to GHCR
uses: docker/login-action@v3
Expand Down Expand Up @@ -77,7 +77,44 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build and push
# Build once and load locally (no registry push yet) so the smoke test
# can gate publication — a broken image must never reach its final tag.
# `cache-to` is populated here so the publish step below is a near-instant
# cache hit of the exact same image.
- name: Build and load for smoke test
uses: docker/build-push-action@v6
with:
context: .
load: true
push: false
tags: mocktioneer:ci-smoke
platforms: linux/amd64
build-args: RUST_VERSION=${{ steps.rust.outputs.version }}
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Smoke test — reachable on mapped port and serves bids
run: |
cid="$(docker run -d -p 8787:8787 mocktioneer:ci-smoke)"
# Wait for the mapped host port — proves the container binds 0.0.0.0,
# not 127.0.0.1 (a loopback bind would make this fail).
for _ in $(seq 1 30); do
curl -fsS http://127.0.0.1:8787/ >/dev/null 2>&1 && break
sleep 2
done
curl -fsS http://127.0.0.1:8787/ >/dev/null
# The baked-in config blob should let the auction endpoint serve a bid.
code="$(curl -s -o /dev/null -w '%{http_code}' -X POST http://127.0.0.1:8787/openrtb2/auction \
-H 'content-type: application/json' \
-d '{"id":"t","imp":[{"id":"1","banner":{"w":300,"h":250}}]}')"
echo "auction status: $code"
docker logs "$cid" 2>&1 | tail -20 || true
docker rm -f "$cid" >/dev/null 2>&1 || true
test "$code" = "200"

# Only now publish — reuses the gha cache from the build above, so this
# pushes the exact image the smoke test just validated (not a rebuild).
- name: Push validated image
uses: docker/build-push-action@v6
with:
context: .
Expand All @@ -87,4 +124,3 @@ jobs:
platforms: linux/amd64
build-args: RUST_VERSION=${{ steps.rust.outputs.version }}
cache-from: type=gha
cache-to: type=gha,mode=max
4 changes: 2 additions & 2 deletions .github/workflows/format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:

- name: Retrieve Rust version
id: rust-version
run: echo "rust-version=$(grep '^rust ' .tool-versions | awk '{print $2}')" >> $GITHUB_OUTPUT
run: echo "rust-version=$(grep '^rust ' .tool-versions | awk '{print $2}')" >> "$GITHUB_OUTPUT"
shell: bash

- name: Set up rust toolchain
Expand Down Expand Up @@ -64,7 +64,7 @@ jobs:
- name: Retrieve Node.js version
id: node-version
working-directory: .
run: echo "node-version=$(grep '^nodejs ' .tool-versions | awk '{print $2}')" >> $GITHUB_OUTPUT
run: echo "node-version=$(grep '^nodejs ' .tool-versions | awk '{print $2}')" >> "$GITHUB_OUTPUT"
shell: bash

- name: Use Node.js
Expand Down
30 changes: 24 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
- name: Retrieve Rust version
id: rust-version
run: echo "rust-version=$(grep '^rust ' .tool-versions | awk '{print $2}')" >> $GITHUB_OUTPUT
run: echo "rust-version=$(grep '^rust ' .tool-versions | awk '{print $2}')" >> "$GITHUB_OUTPUT"
shell: bash

- name: Set up Rust tool chain
Expand All @@ -52,6 +52,24 @@ jobs:
- name: Check feature compilation
run: cargo check --workspace --all-targets --features "fastly cloudflare"

- name: Validate typed app config
run: |
# `mocktioneer.toml` is gitignored (per-env); the committed template is
# `mocktioneer.toml.example`. Materialise it so `config validate` (which
# reads the `<app-name>.toml` default path) has a file to check.
cp mocktioneer.toml.example mocktioneer.toml
cargo run -p mocktioneer-cli -- config validate --strict
- name: Seed a non-default cpm and assert it round-trips (axum)
Comment thread
aram356 marked this conversation as resolved.
run: |
printf 'bid_cpm = 0.35\n' > "${RUNNER_TEMP}/seed.toml"
cargo run -p mocktioneer-cli -- config push --adapter axum --yes --app-config "${RUNNER_TEMP}/seed.toml"
# edgezero #269 stores the typed config as a single blob envelope under
# the store key; bid_cpm lives at `<key> | fromjson | .data.bid_cpm`.
got="$(jq -r '.mocktioneer_config | fromjson | .data.bid_cpm' .edgezero/local-config-mocktioneer_config.json)"
test "$got" = "0.35"
rm -f .edgezero/local-config-mocktioneer_config.json
adapter-wasm-tests:
name: ${{ matrix.adapter }} wasm tests
runs-on: ubuntu-latest
Expand All @@ -68,8 +86,8 @@ jobs:
runner_env: CARGO_TARGET_WASM32_WASIP1_RUNNER
runner_value: viceroy run
- adapter: spin
target: wasm32-wasip1
runner_env: CARGO_TARGET_WASM32_WASIP1_RUNNER
target: wasm32-wasip2
runner_env: CARGO_TARGET_WASM32_WASIP2_RUNNER
runner_value: wasmtime run
steps:
- uses: actions/checkout@v6
Expand All @@ -89,7 +107,7 @@ jobs:
- name: Retrieve Rust version
id: rust-version
run: echo "rust-version=$(grep '^rust ' .tool-versions | awk '{print $2}')" >> $GITHUB_OUTPUT
run: echo "rust-version=$(grep '^rust ' .tool-versions | awk '{print $2}')" >> "$GITHUB_OUTPUT"
shell: bash

- name: Set up Rust tool chain
Expand Down Expand Up @@ -183,8 +201,8 @@ jobs:
- name: Retrieve tool versions
id: tool-versions
run: |
echo "rust=$(grep '^rust ' .tool-versions | awk '{print $2}')" >> $GITHUB_OUTPUT
echo "node=$(grep '^nodejs ' .tool-versions | awk '{print $2}')" >> $GITHUB_OUTPUT
echo "rust=$(grep '^rust ' .tool-versions | awk '{print $2}')" >> "$GITHUB_OUTPUT"
echo "node=$(grep '^nodejs ' .tool-versions | awk '{print $2}')" >> "$GITHUB_OUTPUT"
shell: bash

- name: Set up Rust tool chain
Expand Down
9 changes: 7 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,14 @@ node_modules/
playwright-report/
test-results/

# Cloudflare Workers
.wrangler/
# EdgeZero local config/kv state (config push --adapter axum, etc.)
.edgezero/

# Cloudflare
.wrangler/

# Spin
.spin/

# Mocktioneer
mocktioneer.toml
27 changes: 20 additions & 7 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Mocktioneer is a deterministic OpenRTB banner bidder for edge platforms. It lets
you test client integrations (Prebid.js, Prebid Server, custom SDKs) without
depending on third-party bidders or origin backends. Write once, deploy to
Fastly Compute, Cloudflare Workers, or native Axum servers. The codebase is a
Cargo workspace with 4 crates under `crates/`, a VitePress documentation site
Cargo workspace with 6 crates under `crates/`, a VitePress documentation site
under `docs/`, Playwright e2e tests under `tests/playwright/`, and CI workflows
under `.github/workflows/`.

Expand All @@ -18,7 +18,8 @@ crates/
mocktioneer-adapter-axum/ # Native Axum HTTP server
mocktioneer-adapter-cloudflare/ # Cloudflare Workers bridge (wasm32-unknown-unknown)
mocktioneer-adapter-fastly/ # Fastly Compute bridge (wasm32-wasip1)
mocktioneer-adapter-spin/ # Spin / Fermyon bridge (wasm32-wasip1)
mocktioneer-adapter-spin/ # Spin / Fermyon bridge (wasm32-wasip2)
mocktioneer-cli/ # Custom CLI: edgezero commands + typed config validate/push
docs/ # VitePress documentation site (Node.js)
examples/ # curl/shell scripts for endpoint demos
tests/playwright/ # Playwright e2e tests (creative visibility, sizes)
Expand Down Expand Up @@ -52,7 +53,12 @@ cargo run -p mocktioneer-adapter-axum
# Run via EdgeZero CLI
edgezero-cli serve --adapter cloudflare # Cloudflare on :8787
edgezero-cli serve --adapter fastly # Fastly on :7676
edgezero-cli serve --adapter spin # Spin on :3000
edgezero-cli serve --adapter spin # Spin on :3000 — NOTE: `spin up` is
# currently blocked (spin-sdk 6.0.0
# imports wasi:http@0.3.0-rc, which no
# released Spin runtime provides).
# Build + wasmtime contract tests pass;
# live serve needs an upstream fix.

# Playwright e2e tests
cd tests/playwright && npm test
Expand All @@ -70,7 +76,7 @@ faster iteration since nearly all business logic lives there.
| ---------- | ------------------------ | ---------------------------------------------------- |
| Fastly | `wasm32-wasip1` | Requires Viceroy for local testing |
| Cloudflare | `wasm32-unknown-unknown` | Requires `wrangler` for dev/deploy |
| Spin | `wasm32-wasip1` | Requires `spin` for dev/deploy; tests via `wasmtime` |
| Spin | `wasm32-wasip2` | Requires `spin` for dev/deploy; tests via `wasmtime` |
| Axum | Native (host triple) | Standard Tokio runtime |

## Coding Conventions
Expand Down Expand Up @@ -154,7 +160,12 @@ through `render.rs`. Do not inline ad markup in handlers.

## Key Constants

- `FIXED_BID_CPM: f64 = 0.20` — fixed price for all Mocktioneer-generated bids
- `FIXED_BID_CPM: f64 = 0.20` — the auction/APS builders' default `cpm`
argument and the shipped value in `mocktioneer.toml`. At runtime the
OpenRTB/APS handlers read `bid_cpm` from the typed `MocktioneerConfig` blob via
the fail-loud `AppConfig` extractor (edgezero #269 blob model), so a deploy
must `config push` once before those endpoints serve — it is **not** a runtime
fallback
- `STANDARD_SIZES` — 13 standard IAB sizes as a const array (300x250, 728x90, 320x50, etc.)

## CI Gates
Expand All @@ -165,8 +176,10 @@ Every PR must pass:
2. `cargo clippy --workspace --all-targets --all-features -- -D warnings`
3. `cargo test --workspace --all-targets`
4. `cargo check --workspace --all-targets --features "fastly cloudflare"`
5. Playwright e2e tests (`tests/playwright/`)
6. ESLint + Prettier on `docs/`
5. `cargo run -p mocktioneer-cli -- config validate --strict --app-config mocktioneer.toml.example`
(`mocktioneer.toml` is gitignored; CI copies the template first — see `test.yml`)
6. Playwright e2e tests (`tests/playwright/`)
7. ESLint + Prettier on `docs/`

Docker image is built and pushed to `ghcr.io/stackpop/mocktioneer` on push to
main and on releases.
Expand Down
Loading
Loading