Skip to content

Add Platformatic World to worlds-manifest.json#1450

Open
marcopiraccini wants to merge 3 commits intovercel:mainfrom
marcopiraccini:vercel-submission
Open

Add Platformatic World to worlds-manifest.json#1450
marcopiraccini wants to merge 3 commits intovercel:mainfrom
marcopiraccini:vercel-submission

Conversation

@marcopiraccini
Copy link
Copy Markdown

Summary

  • Add @platformatic/world as a community world backed by a centralized workflow service (@platformatic/workflow) with PostgreSQL
  • Introduce a generic docker service type in the CI so worlds can declare arbitrary Docker containers in their manifest services array
  • Services are started with --network host and health-checked from the runner

How it works

Platformatic World is a thin HTTP client that talks to an external workflow service. The CI needs two containers:

  1. postgres — database for the workflow service
  2. platformatic-workflow — the workflow service (platformatic/workflow:latest from Docker Hub)

Both run with --network host so they share localhost with the test runner. The matrix script sets service-type: "docker" for any world whose services aren't the built-in mongodb/redis, and passes the full services JSON to the reusable workflow.

@marcopiraccini marcopiraccini requested a review from a team as a code owner March 19, 2026 15:48
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Mar 19, 2026

🦋 Changeset detected

Latest commit: f112ac4

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Mar 19, 2026

@marcopiraccini is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

Comment thread .github/workflows/e2e-community-world.yml Outdated
Copy link
Copy Markdown
Member

@TooTallNate TooTallNate left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review

Thanks for the contribution. The generic docker service type is a nice generalization — good direction. I have a few things to sort out before this merges.

Context

After the merge from main, this branch now has if: false on both getCommunityWorldsMatrix and e2e-community jobs (from #1783). That means the Platformatic world CI you're adding here will not actually run on main after merge. Community worlds are temporarily disabled in main's CI until they ship CBOR queue transport support.

Before this lands, please confirm that either:

  1. @platformatic/world already supports CBOR queue transport (SPEC_VERSION_SUPPORTS_CBOR_QUEUE_TRANSPORT = 3), OR
  2. You're OK with the job being added but skipped until community worlds are re-enabled

If (1), you might want to coordinate with the Vercel team to re-enable community worlds in main CI alongside this PR.

Blocking issues

  1. No changeset. Per the repo convention (AGENTS.md), every PR requires a changeset. For a CI + manifest-only change, an empty changeset (---\n---) is appropriate — see recent examples like .changeset/skip-community-worlds-main.md.

  2. Shell injection surface / unnecessary eval. See inline comments on the docker step. The eval "$cmd" and sh -c "$health_cmd" execute manifest-provided strings as shell. Since worlds-manifest.json is in-repo and reviewed, the trust boundary is acceptable — but eval should be removed in favor of an array-based docker run invocation, which is safer and clearer.

Non-blocking concerns

See inline comments.

done

- name: Start Docker services
if: ${{ inputs.service-type == 'docker' }}
Copy link
Copy Markdown
Member

@TooTallNate TooTallNate Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary eval + fragile quoting.

cmd="docker run -d --name $name --network host"
for key in $(echo "$svc" | jq -r '.env // {} | keys[]'); do
  val=$(echo "$svc" | jq -r ".env[\"$key\"]")
  cmd="$cmd -e $key=$val"
done
cmd="$cmd $image"
eval "$cmd"

Issues:

  1. eval is unnecessary here. Every variable already works with direct expansion. Replace with an array:

    args=(docker run -d --name "$name" --network host)
    while IFS='=' read -r key val; do
      args+=(-e "$key=$val")
    done < <(echo "$svc" | jq -r '.env // {} | to_entries[] | "\(.key)=\(.value)"')
    args+=("$image")
    "${args[@]}"

    This avoids all shell re-interpretation of values.

  2. Values with spaces/special chars break. If a manifest env value contains a space or quote, cmd="$cmd -e $key=$val" concatenates it unquoted, and eval then splits on whitespace. Not currently exploited by the Platformatic manifest, but a booby trap for future world submissions.

  3. No set -e. A failing docker run (e.g. image pull failure) lets the loop continue and the test run proceeds anyway. Consider set -euo pipefail at the top of the run block.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rewrote as args=(docker run ...) array — no eval, env values with quotes/spaces survive intact. Also added set -euo pipefail so any failure in the step aborts.

if [ -n "$health_cmd" ]; then
echo "Waiting for $name to be ready..."
for i in $(seq 1 "$retries"); do
if sh -c "$health_cmd" &>/dev/null; then
Copy link
Copy Markdown
Member

@TooTallNate TooTallNate Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sh -c "$health_cmd" executes manifest-provided string as shell.

This is explicitly executing the healthCheck.cmd field from the manifest. That's fine given the repo trust boundary (manifest entries are PR-reviewed), but worth being explicit about it in a comment — otherwise a reviewer of a future world PR might not realize the health check string is an executable surface.

Also: the health check uses retries but ignores the manifest's interval and timeout fields (which the Platformatic world declares as "interval": "10s", "timeout": "5s"). The hardcoded sleep 2 between retries means interval is ignored. If you're not going to honor them, consider removing them from the manifest (or document them as informational).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added an explicit comment at the top of the step calling this out so the assumption is visible.

echo "$name is ready"
break
fi
if [ "$i" -eq "$retries" ]; then
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: when a health check exhausts retries, this logs WARNING but the job continues, so the subsequent E2E tests will run against a broken service and fail with less actionable errors. Consider exit 1 here so the failure is diagnosed at the health-check step.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Now exit 1 when retries are exhausted.

Comment thread worlds-manifest.json
"ports": ["3042:3042"],
"env": {
"DATABASE_URL": "postgres://wf:wf@localhost:5432/workflow",
"PORT": "3042"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No explicit service dependency declaration. The platformatic-workflow container depends on postgres being ready (it opens DB connections on startup), but the workflow file starts services serially in manifest order and health-checks each one before starting the next. So this works only because postgres is listed first.

If a future world entry lists services in a different order, this will silently break. Consider:

  1. Documenting the ordering requirement in a comment in the YAML, or
  2. Adding an optional dependsOn field per service (future work)

For this PR, just documenting the implicit ordering invariant somewhere would be enough.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Services now start serially and each health check must pass before the next starts, so postgres (listed first) is guaranteed ready before platformatic-workflow boots.
Added a comment in the workflow documenting this ordering requirement.

const serviceName = world.services[0].name;
if (['mongodb', 'redis'].includes(serviceName)) {
serviceType = serviceName;
} else {
Copy link
Copy Markdown
Member

@TooTallNate TooTallNate Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the fallback-to-docker logic means that if a future world entry has services [{ name: "mongodb" }, { name: "redis" }] (two services, neither built-in), the first service name determines the path. With your change, only the first service's name is checked — if it's mongodb or redis, the built-in path is used and the other services are silently ignored. Consider either:

  1. Picking docker if services.length > 1, OR
  2. Explicitly warning / erroring if a non-trivial services array includes a built-in name

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added an explicit services.length > 1 branch that routes straight to the docker path, so any multi-service combo (including the [mongodb, redis] case you raised) gets generic handling instead of the single-service fallback.

Signed-off-by: marcopiraccini <marco.piraccini@gmail.com>
Signed-off-by: marcopiraccini <marco.piraccini@gmail.com>
…runner

Signed-off-by: marcopiraccini <marco.piraccini@gmail.com>
@marcopiraccini
Copy link
Copy Markdown
Author

marcopiraccini commented Apr 20, 2026

@TooTallNate Platformatic now ships CBOR queue transport support as of platformatic/platformatic-world#25 — spec v3 (CBOR + resilient start + streams.*), with the ported Vercel e2e suite passing 61/61 locally against platformatic/workflow:0.7.0 (the image this PR now pins).

@TooTallNate PTAL

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants