Skip to content

Go CLI: add Edge Workers command parity - #3018

Open
rinatkhaziev wants to merge 3 commits into
trunkfrom
codex/go-edge-workers
Open

Go CLI: add Edge Workers command parity#3018
rinatkhaziev wants to merge 3 commits into
trunkfrom
codex/go-edge-workers

Conversation

@rinatkhaziev

@rinatkhaziev rinatkhaziev commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Description

Port the existing Node Edge Workers command set to the Go runtime: init, new, build, validate, list, get, deploy, enable, disable, and delete.

The implementation reuses Go app/environment resolution and authenticated GraphQL middleware. It preserves inactive creation, explicit enablement, production confirmations, prepare-before-write deployment, source omission, location preservation/clearing, and partial-failure reporting. Local AssemblyScript builds still require Node.js and project npm dependencies.

Add equivalent fixtures and real Node-vs-Go comparisons for output, API requests, filesystem effects, parsing, and confirmations. Match Node's terminal-safe JSON escaping and malformed UTF-8 source decoding. The approved executable-name difference is documented in cutover note 1.28: Go Edge Workers help examples and init/new next steps invoke vip-next; Node continues to invoke vip. Shared project templates are unchanged. Node SEA changes are out of scope.

Source display fix

Both runtimes now preserve newlines and tabs in get --source output and normalize CRLF to LF. A source-specific formatter still escapes standalone carriage returns, ANSI escapes, and other terminal controls; metadata escaping and stored source remain unchanged. Literal backslash escape sequences are not decoded.

Regression tests failed in both runtimes before the fix and passed afterward. The real CLI parity scenario also asserts the expected readable output independently, so a shared rendering bug cannot pass merely because both runtimes match.

Go executable guidance

Address Copilot's four review comments by correcting all ten Go help examples and the init/new next steps. Tests render each command's help, assert Node and Go guidance independently, then normalize only those known executable prefixes for parity comparison.

Changelog Description

Added

  • Go CLI: Add the complete Edge Workers command set.

Fixed

  • Edge Workers: Preserve readable source formatting in Node and Go get --source output without allowing unsafe terminal controls.

Verification

Passed locally on macOS:

  • make test, make lint, and make verify-gql-stale.
  • Node build, type checking, and focused ESLint.
  • 255 Node tests across 18 Edge Workers and output-format suites.
  • make test-parity-unit and make test-parity-unit-hostile, including 70 Edge Workers differential scenarios and six terminal-prompt scenarios.
  • Race tests for the Edge Workers, GraphQL input, and output packages.
  • Real compiler smoke: both runtimes scaffolded identical files and compiled identical 3,189-byte WASM with only alloc and on_client_response function exports.

Not verified: make test-parity was attempted, but a required local API service was stopped. App-context discovery failed before any local integration scenario ran. No live Edge Worker was deployed or enabled. Windows execution and host-modifying dev-env E2E tests were not run.

Pull request checklist

  • No new environment variables requiring SETUP.md changes.
  • Update Edge Workers documentation.
  • Add/update automated tests.
  • Complete live local integration parity once its API dependency is available.

Steps to Test

  1. Use the repository's supported Go and Node versions and install Node dependencies.
  2. Run make test, make lint, and make verify-gql-stale.
  3. Run npm run build, npm run check-types, make require-node-vip-bin, make test-parity-unit, and make test-parity-unit-hostile.
  4. For the opt-in compiler check, run NODE_VIP_BIN="$PWD/dist/bin/vip.js" go test -tags='parity edgeworkers_build_smoke' ./internal/parity -run '^TestEdgeWorkersRealCompilerSmoke$' -count=1 -v. This installs pinned compiler dependencies into temporary projects.
  5. With the local integration stack running, run make test-parity.

#### Purpose and Context

Bring the Go runtime up to date with the Node Edge Workers command set.

#### Key Changes

Add all ten commands, project scaffolding and compilation, GraphQL
operations, and deployment planning. Preserve activation safeguards,
source and location semantics, terminal escaping, and error handling.

#### Impact and Considerations

New workers remain inactive unless explicitly enabled. Local builds
still use the project's Node-based AssemblyScript compiler. SEA changes
are excluded.

#### Testing and Validation

Add unit, real runtime differential, terminal prompt, and compiler smoke
coverage. Go tests and vet, Node tests and type checks, and normal and
hostile fixture parity pass. Local integration parity remains unverified
because a required local API service is stopped.
@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 1 package(s) with unknown licenses.
See the Details below.

License Issues

internal/edgeworkers/templates/package.json

PackageVersionLicenseIssue Type
@automattic/vip-edge-workers-sdk0.3.2NullUnknown License

OpenSSF Scorecard

PackageVersionScoreDetails
npm/@automattic/vip-edge-workers-sdk 0.3.2 UnknownUnknown
npm/assemblyscript 0.27.0 🟢 3.9
Details
CheckScoreReason
Code-Review🟢 7Found 20/27 approved changesets -- score normalized to 7
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Maintained🟢 55 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 5
Packaging⚠️ -1packaging workflow not detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
License🟢 10license file detected
Binary-Artifacts🟢 8binaries present in source code
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Signed-Releases⚠️ -1no releases found
Pinned-Dependencies⚠️ 2dependency not pinned by hash detected -- score normalized to 2
Security-Policy⚠️ 0security policy file not detected
Fuzzing⚠️ 0project is not fuzzed
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0

Scanned Files

  • internal/edgeworkers/templates/package.json

#### Purpose and Context

Both runtimes print stored worker source through the single-line
terminal sanitizer. It turns ordinary newlines and tabs into literal
Unicode escape sequences, making get --source output unreadable.

#### Key Changes

Add source-specific escaping in Node and Go and use it only when
rendering stored source. Preserve LF and horizontal tabs, normalize
CRLF to LF, and continue escaping standalone CR, ANSI escapes, and
other C0, DEL, and C1 controls. Keep literal backslash sequences intact.

#### Impact and Considerations

Names, metadata, errors, stored source, and deployment behavior remain
unchanged. The fix is display-only; workers do not need redeployment.

#### Testing and Validation

Reproduce the failure before the fix in both unit suites and through
the real CLIs. Add equivalent formatting and terminal-safety cases and
an independent expected-output assertion to source parity so matching
runtime bugs cannot pass. Verify Go tests/vet/build, 255 Node tests,
type checking/lint/build, and normal and hostile fixture parity.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Ports the existing Node.js Edge Workers CLI command set to the Go runtime (vip-next), adds extensive Node-vs-Go parity coverage (scenarios, prompt handling, filesystem and API request comparisons), and fixes get --source rendering in both runtimes to preserve readable formatting while neutralizing unsafe terminal controls.

Changes:

  • Add Go Edge Workers implementation (scaffold/build/validate/list/get/deploy/enable/disable/delete) with app/env resolution, GraphQL middleware, confirmations, and output formatting.
  • Add comprehensive parity scenarios/fixtures plus differential and prompt-parity tests to compare Node vs Go behavior (stdout/stderr, requests, filesystem effects, prompts).
  • Fix get --source output formatting in Node and Go to preserve newlines/tabs and normalize CRLF→LF while escaping other terminal control characters.

Reviewed changes

Copilot reviewed 126 out of 128 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
testdata/parity/edge-workers-validate.yaml Parity scenario for edge-workers validate happy path.
testdata/parity/edge-workers-validate-null.yaml Parity scenario for null validation response handling.
testdata/parity/edge-workers-validate-no-name.yaml Parity scenario for missing name validation error.
testdata/parity/edge-workers-validate-no-artifact.yaml Parity scenario for missing prebuilt artifact error.
testdata/parity/edge-workers-validate-name-all.yaml Parity scenario for conflicting name + --all.
testdata/parity/edge-workers-validate-invalid.yaml Parity scenario for invalid worker validation.
testdata/parity/edge-workers-validate-all.yaml Parity scenario for validate --all.
testdata/parity/edge-workers-unicode-order.yaml Parity scenario covering unicode worker ordering behavior.
testdata/parity/edge-workers-table-control-name.yaml Parity scenario for table output with control chars in names.
testdata/parity/edge-workers-short-equals.yaml Parity scenario for short-flag -x=value parsing.
testdata/parity/edge-workers-repeated-type.yaml Parity scenario for repeated --type flag behavior.
testdata/parity/edge-workers-repeated-path.yaml Parity scenario for repeated --path flag behavior.
testdata/parity/edge-workers-read-null.yaml Parity scenario for null read envelope behavior.
testdata/parity/edge-workers-new.yaml Parity scenario for edge-workers new.
testdata/parity/edge-workers-new-location.yaml Parity scenario for new --location.
testdata/parity/edge-workers-new-invalid-name.yaml Parity scenario for invalid worker name handling.
testdata/parity/edge-workers-new-invalid-location.yaml Parity scenario for invalid location handling.
testdata/parity/edge-workers-mutation-null.yaml Parity scenario for null mutation response handling.
testdata/parity/edge-workers-mutation-graphql-error.yaml Parity scenario for GraphQL error handling on mutation.
testdata/parity/edge-workers-list-table.yaml Parity scenario for list table output.
testdata/parity/edge-workers-list-json.yaml Parity scenario for list JSON output.
testdata/parity/edge-workers-list-empty.yaml Parity scenario for empty list behavior.
testdata/parity/edge-workers-list-empty-json.yaml Parity scenario for empty list in JSON mode.
testdata/parity/edge-workers-list-csv.yaml Parity scenario for list CSV output.
testdata/parity/edge-workers-json-control-name.yaml Parity scenario for JSON output escaping with control chars in names.
testdata/parity/edge-workers-init.yaml Parity scenario for project init.
testdata/parity/edge-workers-init-nonempty.yaml Parity scenario for init refusal on non-empty dir.
testdata/parity/edge-workers-init-invalid-type.yaml Parity scenario for invalid init type handling.
testdata/parity/edge-workers-get.yaml Parity scenario for get details.
testdata/parity/edge-workers-get-source.yaml Parity scenario for get --source formatting + safety.
testdata/parity/edge-workers-get-no-source.yaml Parity scenario when --source requested but none stored.
testdata/parity/edge-workers-get-missing.yaml Parity scenario for missing worker handling.
testdata/parity/edge-workers-get-empty-source.yaml Parity scenario for empty stored source handling.
testdata/parity/edge-workers-entry-escape.yaml Parity scenario ensuring entry path traversal is rejected.
testdata/parity/edge-workers-enable.yaml Parity scenario for enabling a worker.
testdata/parity/edge-workers-enable-production-refused.yaml Parity scenario for production enable confirmation refusal.
testdata/parity/edge-workers-duplicate-names.yaml Parity scenario for duplicate worker names detection.
testdata/parity/edge-workers-double-dash.yaml Parity scenario for -- boundary parsing.
testdata/parity/edge-workers-disable.yaml Parity scenario for disabling a worker.
testdata/parity/edge-workers-deploy-upload-failure.yaml Parity scenario for partial deploy upload failure.
testdata/parity/edge-workers-deploy-source-empty.yaml Parity scenario for deploying with empty source.
testdata/parity/edge-workers-deploy-skip-validate.yaml Parity scenario for deploy --skip-validate.
testdata/parity/edge-workers-deploy-skip-source.yaml Parity scenario for deploy --skip-source on update.
testdata/parity/edge-workers-deploy-skip-source-create.yaml Parity scenario for --skip-source on create.
testdata/parity/edge-workers-deploy-production-skip.yaml Parity scenario for prod deploy with --skip-confirmation.
testdata/parity/edge-workers-deploy-production-refused.yaml Parity scenario for prod deploy refusal without confirmation.
testdata/parity/edge-workers-deploy-name-all.yaml Parity scenario for deploy name + --all conflict.
testdata/parity/edge-workers-deploy-location-replace.yaml Parity scenario for location replace behavior.
testdata/parity/edge-workers-deploy-location-preserve.yaml Parity scenario for location preserve behavior.
testdata/parity/edge-workers-deploy-location-clear.yaml Parity scenario for clearing location on update.
testdata/parity/edge-workers-deploy-inactive-update.yaml Parity scenario for updating inactive worker.
testdata/parity/edge-workers-deploy-inactive-update-enable.yaml Parity scenario for update + enable.
testdata/parity/edge-workers-deploy-enable-failure.yaml Parity scenario for enable failure after upload.
testdata/parity/edge-workers-deploy-create.yaml Parity scenario for create via deploy.
testdata/parity/edge-workers-deploy-create-enable.yaml Parity scenario for create + enable via deploy.
testdata/parity/edge-workers-deploy-all-preparation-failure.yaml Parity scenario ensuring prepare-before-write semantics.
testdata/parity/edge-workers-deploy-active-update.yaml Parity scenario for updating active worker.
testdata/parity/edge-workers-deploy-active-update-enable.yaml Parity scenario for active update with --enable.
testdata/parity/edge-workers-delete-rejected.yaml Parity scenario for delete rejected by API.
testdata/parity/edge-workers-delete-force.yaml Parity scenario for delete with --force.
testdata/parity/edge-workers-build-one.yaml Parity scenario for building one worker.
testdata/parity/edge-workers-build-name-all.yaml Parity scenario for build name + --all conflict.
testdata/parity/edge-workers-build-missing-compiler.yaml Parity scenario for missing compiler error.
testdata/parity/edge-workers-build-empty.yaml Parity scenario for build with no workers.
testdata/parity/edge-workers-build-compiler-error.yaml Parity scenario for compiler failure diagnostics.
testdata/parity/edge-workers-build-all.yaml Parity scenario for build --all.
testdata/parity/edge-workers-bare-type.yaml Parity scenario for bare optional --type parsing.
testdata/parity/edge-workers-bare-path.yaml Parity scenario for bare optional --path parsing.
testdata/parity/edge-workers-bare-location.yaml Parity scenario for bare optional --location parsing.
testdata/parity/edge-workers-artifact-symlink.yaml Parity scenario preventing artifact symlink escape.
testdata/parity-local/edge-workers/two-workers/workers/b/worker.json Local fixture worker manifest.
testdata/parity-local/edge-workers/two-workers/workers/b/assembly/index.ts Local fixture worker source.
testdata/parity-local/edge-workers/two-workers/workers/a/worker.json Local fixture worker manifest.
testdata/parity-local/edge-workers/two-workers/workers/a/assembly/index.ts Local fixture worker source.
testdata/parity-local/edge-workers/two-workers/edge-workers.json Local fixture project descriptor.
testdata/parity-local/edge-workers/basic/workers/headers/worker.json Local fixture worker manifest.
testdata/parity-local/edge-workers/basic/workers/headers/assembly/index.ts Local fixture worker source.
testdata/parity-local/edge-workers/basic/edge-workers.json Local fixture project descriptor.
src/lib/edge-workers/output.ts Add escapeTerminalSource for safe readable source output.
src/bin/vip-edge-workers-get.js Use source-specific escaping for get --source.
internal/parity/surface_differential_test.go Exclude edge-worker scenarios from the generic surface inventory.
internal/parity/runner.go Add per-run working directory support.
internal/parity/runner_test.go Test runner working directory behavior.
internal/parity/edge_workers_prompt_test.go Add PTY-based prompt parity tests (non-Windows).
internal/parity/edge_workers_differential_test.go Add full Node-vs-Go differential harness for Edge Workers.
internal/parity/edge_workers_cases_test.go Declare Edge Workers differential scenario inventory.
internal/parity/edge_workers_build_smoke_test.go Opt-in real compiler smoke test for both runtimes.
internal/output/output_test.go Add JSON control-character escaping test coverage.
internal/output/json.go Escape DEL/C1 in rendered JSON to match Node terminal-safe behavior.
internal/gql/schema.gql Extend schema with edge worker validation and updated mutation docs.
internal/gql/operations/edge_workers.graphql Add Edge Workers queries/mutations used by Go runtime.
internal/gql/genqlient.yaml Bind edge worker mutation inputs to custom marshaler types.
internal/gql/edgeworkerinput/input.go Custom JSON marshaling to preserve omitted/null/empty semantics.
internal/gql/edgeworkerinput/input_test.go Tests for presence/omission semantics in mutation inputs.
internal/edgeworkers/validation.go Validation helpers for names/paths/location parsing and containment.
internal/edgeworkers/types.go Define Edge Workers domain types and API interface.
internal/edgeworkers/templates/worker.ts Scaffolded AssemblyScript worker template.
internal/edgeworkers/templates/tsconfig.json Scaffolded tsconfig template.
internal/edgeworkers/templates/README.md Scaffolded project README.
internal/edgeworkers/templates/package.json Scaffolded package.json with pinned SDK/compiler deps.
internal/edgeworkers/templates/gitignore Scaffolded .gitignore template.
internal/edgeworkers/templates/edge-workers.json Scaffolded project descriptor template.
internal/edgeworkers/scaffold.go Implement project/worker scaffolding in Go.
internal/edgeworkers/project.go Implement project discovery + manifest/descriptor parsing in Go.
internal/edgeworkers/project_test.go Tests for discovery, sorting, parsing, symlink safety.
internal/edgeworkers/output.go Implement terminal-safe output formatting (incl. source).
internal/edgeworkers/output_test.go Tests for output escaping + confirmation messaging.
internal/edgeworkers/deployment.go Plan/prepare/apply deployment logic with prepare-before-write.
internal/edgeworkers/deployment_test.go Tests for partial failure, presence, active state semantics.
internal/edgeworkers/confirmation.go Implement production confirmations and deletion confirmation.
internal/edgeworkers/build.go Build via AssemblyScript compiler and safe artifact/source reads.
internal/edgeworkers/build_test.go Tests for scaffolding safety, compiler args, UTF-8 replacement, symlinks.
internal/edgeworkers/api.go Go GraphQL client wrapper for Edge Workers operations.
internal/edgeworkers/api_test.go Tests for payloads, read envelopes, rechallenge caching, retry rules.
go.mod Promote golang.org/x/text to direct dependency (used by new code).
docs/EDGE-WORKERS.md Document Go runtime command availability + source rendering rules.
cmd/vip-next/root.go Register new edge-workers command in Go CLI.
cmd/vip-next/flags_node_parity_test.go Add short-flag parity mappings for edge-workers commands.
cmd/vip-next/edge_workers_test.go Root command wiring + parsing/help marker tests for edge-workers.
cmd/vip-next/commands/edge_workers.go Core command wiring, shared helpers, app/env integration.
cmd/vip-next/commands/edge_workers_test.go Go command-level tests for lifecycle, validation, telemetry, non-interactive behavior.
cmd/vip-next/commands/edge_workers_read.go Implement list/get/validate commands.
cmd/vip-next/commands/edge_workers_mutation.go Implement deploy/enable/disable/delete commands.
cmd/vip-next/commands/edge_workers_local.go Implement init/new/build local commands.
cmd/vip-next/commands/edge_workers_flags.go Implement optional-value flag handling for Node parity.
tests/lib/edge-workers/project.js Extend Node tests for malformed UTF-8 source replacement.
tests/bin/vip-edge-workers-get.js Add Node tests for safe readable get --source rendering.
Suppressed comments (3)

cmd/vip-next/commands/edge_workers_local.go:49

  • The command examples use vip ... even though the Go binary root command is vip-next, which can confuse users reading --help.
	c := &cobra.Command{Use: "new <name>", Short: "Add a new worker to an edge-workers project.", Example: "  vip edge-workers new add-security-headers\n  vip edge-workers new my-worker --path ./infra/edge\n  vip edge-workers new api-auth --location starts_with:/api/"}

cmd/vip-next/commands/edge_workers_read.go:33

  • This help example uses vip ... even though the Go CLI entrypoint is vip-next. Since this is copy/paste guidance, it should match the actual binary name.
	c := &cobra.Command{Use: "get <name>", Short: "Retrieve details for a single deployed edge worker.", Example: "  vip @example-app.production edge-workers get my-worker\n  vip @example-app.production edge-workers get my-worker --source"}

cmd/vip-next/commands/edge_workers_mutation.go:77

  • This help example uses vip ... even though the Go CLI root command is vip-next. Using the correct binary name prevents copy/paste mistakes from --help.
	c := &cobra.Command{Use: action + " <name>", Short: verb + " a deployed edge worker.", Example: "  vip @example-app.production edge-workers " + action + " my-worker"}

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread cmd/vip-next/commands/edge_workers_local.go Outdated
Comment thread cmd/vip-next/commands/edge_workers_local.go Outdated
Comment thread cmd/vip-next/commands/edge_workers_read.go Outdated
Comment thread cmd/vip-next/commands/edge_workers_mutation.go Outdated
#### Purpose and Context

The Go Edge Workers examples and scaffold next steps point at the Node
vip executable. Copying them can switch runtimes unintentionally.

#### Key Changes

Use vip-next in all ten Go help examples and the init/new next-step
messages. Leave Node guidance and shared project templates unchanged.

#### Impact and Considerations

Document the approved executable-name difference in the cutover notes.
Parity first checks each runtime's actual executable name, then
normalizes only the known init/new guidance prefixes. Arguments,
source contents, filesystem effects, and API requests still compare.

#### Testing and Validation

Add rendered-help coverage for all ten Go commands and next-step
assertions in both runtimes. Verify expected failures before the fix,
then run Go tests, vet/build, Node init/new tests and lint, and real
Node-vs-Go fixture parity in normal and hostile environments.
@sonarqubecloud

Copy link
Copy Markdown

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