Skip to content

fix: pass regional Flight gRPC URL; correct app-url to spice.ai/<org>/<app>#15

Merged
lukekim merged 1 commit into
trunkfrom
fix/sdk-http-only-and-app-url
May 3, 2026
Merged

fix: pass regional Flight gRPC URL; correct app-url to spice.ai/<org>/<app>#15
lukekim merged 1 commit into
trunkfrom
fix/sdk-http-only-and-app-url

Conversation

@lukekim
Copy link
Copy Markdown
Contributor

@lukekim lukekim commented May 3, 2026

Summary

Two fixes from the latest failed deploy on `lukekim/home`:

```
##[error]✗ sql (4769ms) — 14 UNAVAILABLE: No connection established. Last error: null. Resolution note:

App URL: https://home.spice.ai ← wrong; should be https://spice.ai/lukekim/home
```

1. SQL probe `14 UNAVAILABLE: No connection established`

The `@spiceai/spice` SDK was instantiated without a `flightUrl`, so its gRPC client targeted the default localhost:50051 and failed. Per the Spice Cloud Flight docs, the regional endpoint is `-prod-aws-flight.spiceai.io:443` (mirrors the data hostname with `-data` swapped for `-flight` — so `us-west-2-prod-aws-data.spiceai.io` → `us-west-2-prod-aws-flight.spiceai.io:443`). The action now derives that from the resolved app's cname / region and passes it through to `RuntimeClient` → `SpiceClient`. Per @lukekim's preference we keep gRPC as the primary transport (with the SDK's HTTP fallback) rather than forcing `httpOnly: true`.

New `flight-url` input override accepts `host:port` or `grpc+tls://host:port` form (scheme is stripped before passing to the SDK).

2. `app-url` was wrong

Apps live at `https://spice.ai//`, not `https://.spice.ai`. New `buildAppUrl` helper constructs the right URL using:

  1. the new `org` input when set, else
  2. the owner part of `GITHUB_REPOSITORY` (matches the Spice org slug for personal orgs and orgs created from a connected GitHub organization), else
  3. `https://spice.ai/apps\` as a last-ditch fallback.

So a workflow on `lukekim/home` now outputs `https://spice.ai/lukekim/home\`.

Node 24 verification

Confirmed every Node-version pin is on 24 already (set in #13):

```
action.yml runs.using: node24
package.json scripts.build: esbuild --target=node24 …
package.json engines.node: ">=24"
.nvmrc: 24
.github/workflows/ci.yml: node-version: 24 (×2)
.github/workflows/release.yml: node-version: 24
```

The Node 20 deprecation warning seen in the latest workflow log is for `actions/checkout@…` (third-party, pinned by the user's workflow), not this action.

Test plan

  • `npm run all` — 101 tests passing (up from 93), lint/typecheck/build/dist freshness clean.
  • CI green on this PR.
  • Manual: re-run `lukekim/home` workflow on the merged commit and confirm:

…/<app>

Two fixes from the latest failed deploy run.

1. SQL probe `14 UNAVAILABLE: No connection established`
   The @spiceai/spice SDK was initialized without `flightUrl`, so its
   gRPC client targeted the default localhost:50051. Per the Spice docs
   the regional flight endpoint is
   `<region>-prod-aws-flight.spiceai.io:443` (mirrors the data hostname
   with `-data` swapped for `-flight`). Derive that from the resolved
   app's cname / region and pass it through to `RuntimeClient` →
   `SpiceClient`. Add a `flight-url` input override that accepts
   `host:port` or `grpc+tls://host:port` form (scheme is stripped).

2. `app-url` was wrong
   Apps live at `https://spice.ai/<org>/<app-name>`, not
   `https://<app-name>.spice.ai`. New helper `buildAppUrl` constructs
   the right URL using the new `org` input, falling back to the owner
   part of `GITHUB_REPOSITORY` (which matches the Spice org slug for
   personal orgs and connected GitHub orgs), and finally to
   `https://spice.ai/apps` if neither is available.

Tests: 101 passing (up from 93). New cases cover flight URL derivation
from cname / region / explicit input / scheme stripping, and the
buildAppUrl org-precedence logic.
Copilot AI review requested due to automatic review settings May 3, 2026 00:38
@lukekim lukekim merged commit 074f5c2 into trunk May 3, 2026
6 checks passed
@lukekim lukekim deleted the fix/sdk-http-only-and-app-url branch May 3, 2026 00:41
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes Spice Cloud deploy action outputs and runtime probe connectivity by deriving correct portal URLs and configuring the Spice SDK with a regional Arrow Flight endpoint.

Changes:

  • Construct app-url output using https://spice.ai/<org>/<app> via new org input + GITHUB_REPOSITORY fallback.
  • Add flight-url input and derive a default regional Flight gRPC endpoint to pass through to RuntimeClient/SpiceClient.
  • Add/extend tests for URL resolution behavior and update docs/changelog to reflect the fixes.

Reviewed changes

Copilot reviewed 8 out of 10 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/main.ts Switches app-url output to buildAppUrl(...) and introduces the helper.
src/inputs.ts Adds org and flightUrl inputs plus Flight URL derivation/helpers and parsing logic.
src/deploy.ts Resolves and logs Flight URL, and passes it into the runtime client used by probes.
action.yml Documents new org and flight-url inputs and clarifies runtime-url as HTTP.
__tests__/main.test.ts Adds unit tests for buildAppUrl.
__tests__/deploy.test.ts Adds unit tests for resolveFlightUrl.
README.md Updates app-url output documentation to the canonical portal pattern.
CHANGELOG.md Records the new inputs and the two fixes under Unreleased.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread __tests__/deploy.test.ts
Comment on lines +322 to +326
it("respects explicit flight-url override (with scheme stripping)", () => {
expect(
resolveFlightUrl(sampleApp, { ...baseInputs, flightUrl: "custom-flight.example:443" }),
).toBe("custom-flight.example:443");
});
Comment thread src/deploy.ts
Comment on lines +139 to +152
/**
* Resolve the regional Flight gRPC endpoint (`host:port`) for the SDK. Prefer
* an explicit `flight-url` input, then derive from the app's cname (replacing
* `-data` with `-flight`), then from the app's region, then from the input
* region. Returns `undefined` if no source is available — callers fall back to
* letting the SDK use HTTP.
*/
export function resolveFlightUrl(app: App, inputs: ActionInputs): string | undefined {
if (inputs.flightUrl) return inputs.flightUrl;
if (app.cname) return deriveFlightUrlFromCname(app.cname);
if (app.region) return deriveFlightUrl(app.region);
if (inputs.region) return deriveFlightUrl(inputs.region);
return undefined;
}
Comment thread src/inputs.ts
Comment on lines +200 to +204
// Flight URL is `host:port` (gRPC), not an HTTP URL — don't validate as URL.
// Strip an optional `grpc+tls://` / `grpc://` scheme so docs-style values work.
const flightUrlRaw = getOptional("flight-url");
const flightUrl = flightUrlRaw?.replace(/^grpc(\+tls)?:\/\//, "");

Comment thread README.md
| `app-id` | Resolved numeric app ID. |
| `app-name` | Resolved app name. |
| `app-url` | `https://<app-name>.spice.ai`. |
| `app-url` | Portal URL of the deployed app: `https://spice.ai/<org>/<app-name>`. The `<org>` slug comes from the `org` input when set, otherwise the owner part of `GITHUB_REPOSITORY`. |
Comment thread CHANGELOG.md
Comment on lines +9 to 19
### Added
- New `org` input. The action now constructs the `app-url` output as `https://spice.ai/<org>/<app-name>` (the canonical Spice Cloud portal URL pattern). When `org` is unset, it falls back to the owner part of `GITHUB_REPOSITORY`, which matches the Spice org slug for personal orgs and orgs created from a connected GitHub organization.
- New `flight-url` input. The action now passes a regional Apache Arrow Flight gRPC endpoint to the `@spiceai/spice` SDK so the SQL probe uses gRPC instead of falling through to localhost. When `flight-url` is unset, it's derived from the resolved app's region as `<region>-prod-aws-flight.spiceai.io:443` (mirrors the data hostname with `-data` swapped for `-flight`). A `grpc+tls://` / `grpc://` scheme prefix on the input is stripped automatically.

### Fixed
- The `app-url` output was previously `https://<app-name>.spice.ai`, which doesn't resolve. It is now `https://spice.ai/<org>/<app-name>` (e.g. `https://spice.ai/lukekim/home`).
- SQL smoke test failed with `14 UNAVAILABLE: No connection established` because the SDK initialized a gRPC client with no `flightUrl` configured for Spice Cloud. The action now derives a regional flight URL by default; the SDK uses gRPC for SQL queries with HTTP fallback as it was designed to.

### Added
- Auto-capture a `repository` tag from `GITHUB_REPOSITORY` when set, sanitized to fit the API's tag-value rule (`/` → `_`). Users can override by setting `repository:` explicitly in the `tags` input.
- New post-deploy dataset readiness check: poll `GET /v1/datasets?status=true` until every dataset reaches a terminal-ok state (`ready`, `disabled`, or `refreshing`); fail the job immediately on `error` or on timeout-while-pending — regardless of `fail-on-test-error`, which still only governs runtime-probe results. Statuses like `shuttingdown` and any unrecognized values are treated as still-pending so the loop never returns a false-positive "loaded". Configured via `dataset-ready-timeout-seconds` (default `300`, set `0` to skip). Dataset states are surfaced as a `datasets` action output and as a table in the GitHub job step summary.
Comment thread __tests__/main.test.ts
Comment on lines +3 to +11
vi.mock("@actions/core", () => ({
setFailed: vi.fn(),
setOutput: vi.fn(),
setSecret: vi.fn(),
info: vi.fn(),
summary: { addHeading: vi.fn(), addTable: vi.fn(), write: vi.fn() },
}));

import { buildAppUrl } from "../src/main.js";
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