Add Platformatic World to worlds-manifest.json#1450
Add Platformatic World to worlds-manifest.json#1450marcopiraccini wants to merge 3 commits intovercel:mainfrom
Conversation
🦋 Changeset detectedLatest commit: f112ac4 The changes in this PR will be included in the next version bump. This PR includes changesets to release 0 packagesWhen 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 |
|
@marcopiraccini is attempting to deploy a commit to the Vercel Labs Team on Vercel. A member of the Team first needs to authorize it. |
There was a problem hiding this comment.
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:
@platformatic/worldalready supports CBOR queue transport (SPEC_VERSION_SUPPORTS_CBOR_QUEUE_TRANSPORT = 3), OR- 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
-
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. -
Shell injection surface / unnecessary
eval. See inline comments on the docker step. Theeval "$cmd"andsh -c "$health_cmd"execute manifest-provided strings as shell. Sinceworlds-manifest.jsonis in-repo and reviewed, the trust boundary is acceptable — butevalshould be removed in favor of an array-baseddocker runinvocation, which is safer and clearer.
Non-blocking concerns
See inline comments.
| done | ||
|
|
||
| - name: Start Docker services | ||
| if: ${{ inputs.service-type == 'docker' }} |
There was a problem hiding this comment.
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:
-
evalis 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.
-
Values with spaces/special chars break. If a manifest env value contains a space or quote,
cmd="$cmd -e $key=$val"concatenates it unquoted, andevalthen splits on whitespace. Not currently exploited by the Platformatic manifest, but a booby trap for future world submissions. -
No
set -e. A failingdocker run(e.g. image pull failure) lets the loop continue and the test run proceeds anyway. Considerset -euo pipefailat the top of therunblock.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Good catch. Now exit 1 when retries are exhausted.
| "ports": ["3042:3042"], | ||
| "env": { | ||
| "DATABASE_URL": "postgres://wf:wf@localhost:5432/workflow", | ||
| "PORT": "3042" |
There was a problem hiding this comment.
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:
- Documenting the ordering requirement in a comment in the YAML, or
- Adding an optional
dependsOnfield per service (future work)
For this PR, just documenting the implicit ordering invariant somewhere would be enough.
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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:
- Picking
dockerifservices.length > 1, OR - Explicitly warning / erroring if a non-trivial
servicesarray includes a built-in name
There was a problem hiding this comment.
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>
…runner Signed-off-by: marcopiraccini <marco.piraccini@gmail.com>
c32c2fb to
f112ac4
Compare
|
@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 |
Summary
@platformatic/worldas a community world backed by a centralized workflow service (@platformatic/workflow) with PostgreSQLdockerservice type in the CI so worlds can declare arbitrary Docker containers in their manifestservicesarray--network hostand health-checked from the runnerHow it works
Platformatic World is a thin HTTP client that talks to an external workflow service. The CI needs two containers:
platformatic/workflow:latestfrom Docker Hub)Both run with
--network hostso they share localhost with the test runner. The matrix script setsservice-type: "docker"for any world whose services aren't the built-in mongodb/redis, and passes the fullservicesJSON to the reusable workflow.