Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
53 changes: 36 additions & 17 deletions .github/workflows/release-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -606,16 +606,33 @@ jobs:
strategy:
fail-fast: false
matrix:
# win32-arm64 is deliberately absent: no runner builds that kernel yet.
# "universal" carries no kernel and is what users on any other platform
# install, alongside the kernel from a native installer.
target:
- darwin-arm64
- darwin-x64
- linux-arm64
- linux-x64
- win32-x64
- universal
# `kernel: false` targets are packaged and published like any other, but
# ship without a kernel and fall back to a host-installed one.
#
# win32-arm64 is published that way because no runner builds that kernel
# yet. It is still published: Positron's bootstrap asks the gallery for
# an asset by exact targetPlatform, and a target that was never
# published answers 403 rather than falling back to the untargeted
# build, which fails Positron's own Windows arm64 build. A kernel-less
# target answers 200, so the entry can land, and gains a kernel later
# with no change on the Positron side.
#
# "universal" answers requests that carry no targetPlatform at all.
include:
- target: darwin-arm64
kernel: true
- target: darwin-x64
kernel: true
- target: linux-arm64
kernel: true
- target: linux-x64
kernel: true
- target: win32-x64
kernel: true
- target: win32-arm64
kernel: false
- target: universal
kernel: false

steps:
- name: Checkout code
Expand All @@ -636,7 +653,7 @@ jobs:
run: npm ci

- name: Download ggsql-jupyter kernel (${{ matrix.target }})
if: matrix.target != 'universal'
if: matrix.kernel
uses: actions/download-artifact@v4
with:
name: ggsql-jupyter-${{ matrix.target }}
Expand All @@ -646,7 +663,7 @@ jobs:
# Artifact upload and download do not preserve the executable bit. The
# extension repairs it at runtime too, but it has to be right inside the
# VSIX for a fresh install to start a session.
if: matrix.target != 'universal'
if: matrix.kernel
run: |
chmod +x ggsql-vscode/bundled/bin/*
ls -l ggsql-vscode/bundled/bin
Expand All @@ -672,18 +689,19 @@ jobs:
working-directory: ggsql-vscode
env:
TARGET: ${{ matrix.target }}
KERNEL: ${{ matrix.kernel }}
VSIX: ${{ steps.package.outputs.vsix }}
run: |
unzip -l "$VSIX"
unzip -p "$VSIX" extension.vsixmanifest \
| grep -o 'TargetPlatform="[^"]*"' || echo 'no TargetPlatform: universal'
if [ "$TARGET" = universal ]; then
if unzip -l "$VSIX" | grep -q 'extension/bundled/'; then
echo "::error::the universal VSIX must not carry a kernel"
if [ "$KERNEL" = true ]; then
if ! unzip -l "$VSIX" | grep -q 'extension/bundled/bin/ggsql-jupyter'; then
echo "::error::the $TARGET VSIX is missing its bundled kernel"
exit 1
fi
elif ! unzip -l "$VSIX" | grep -q 'extension/bundled/bin/ggsql-jupyter'; then
echo "::error::the $TARGET VSIX is missing its bundled kernel"
elif unzip -l "$VSIX" | grep -q 'extension/bundled/'; then
echo "::error::the $TARGET VSIX must not carry a kernel"
exit 1
fi

Expand Down Expand Up @@ -712,6 +730,7 @@ jobs:
- linux-arm64
- linux-x64
- win32-x64
- win32-arm64
- universal

steps:
Expand Down
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
installing the extension is all that is needed to run queries — no separate
native install. The per-platform builds (`darwin-arm64`, `darwin-x64`,
`linux-arm64`, `linux-x64`, `win32-x64`) each carry the same signed kernel
binary the matching installer does, and a kernel-less universal build remains
for any other platform, where the installer is still required. A new
binary the matching installer does. `win32-arm64` and a universal build are
published without a kernel, and still require the native installer. A new
`ggsql.kernelStrategy` setting picks between the bundled kernel (the default),
a kernel installed on the machine, and a fixed path in `ggsql.kernelPath`;
configuring `ggsql.kernelPath` alone continues to mean that path is used.
Expand Down
3 changes: 2 additions & 1 deletion ggsql-vscode/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
- The extension now ships the `ggsql-jupyter` kernel, so installing it is enough
to run queries in Positron. `ggsql.kernelStrategy` picks between the bundled
kernel (the default), a kernel installed on this machine, and a fixed path in
`ggsql.kernelPath`.
`ggsql.kernelPath`. On Windows arm64 the extension ships without a kernel and
uses one installed on the machine.
- Fixed: no ggsql runtime is offered when no kernel can be found, rather than one
that fails at session start with `KS-19: Kernel path not found`.

Expand Down
7 changes: 4 additions & 3 deletions ggsql-vscode/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,15 @@ code --install-extension ggsql-<version>.vsix

A local `vsce package` produces the kernel-less VSIX, since `bundled/` only exists in a release build.

**Release builds** live in [`/.github/workflows/release-packages.yml`](../.github/workflows/release-packages.yml), not in a workflow of their own. Its `build-vsix` job runs a matrix of six — the five platform targets plus `universal` — downloading the `ggsql-jupyter-<target>` artifact each platform job uploaded between signing and installer packaging, restoring the executable bit, and running `vsce package --target <target>`. `publish-openvsx` then publishes the packaged file to Open VSX.
**Release builds** live in [`/.github/workflows/release-packages.yml`](../.github/workflows/release-packages.yml), not in a workflow of their own. Its `build-vsix` job runs a matrix of seven, each entry carrying a `kernel` flag. The five `kernel: true` targets download the `ggsql-jupyter-<target>` artifact each platform job uploaded between signing and installer packaging, restore the executable bit, and run `vsce package --target <target>`. `win32-arm64` and `universal` are `kernel: false` and skip the download. `publish-openvsx` then publishes the packaged file to Open VSX.

Four things about that arrangement are deliberate:
Five things about that arrangement are deliberate:

- **The VSIX build cannot live in its own workflow.** Actions artifacts are scoped to a single workflow run, and two workflows triggered by the same tag run in parallel, so a separate workflow could not download the kernels. Building in the same run also means the kernel and the extension always come from one commit.
- **The executable bit has to be restored after download.** Artifact upload and download drop it. It does survive `vsce package` into the VSIX itself, so restoring it once in CI is enough; `ensureExecutable()` in `manager.ts` is belt-and-braces for an install that loses it.
- **The published artefact is the packaged `.vsix`, with no `target` passed to the publish action.** Open VSX reads the platform from the `TargetPlatform` attribute that `vsce package --target` writes into `extension.vsixmanifest`, and defaults to `universal` when it is absent; `ovsx` discards a target option when handed an already-packaged vsix.
- **`win32-arm64` is not built.** No runner produces that kernel yet. Positron's bootstrap appends `?targetPlatform=<target>` and gets an HTTP 403 rather than the universal build for a target that was never published, so the universal VSIX is not a fallback for it — see posit-dev/positron#14954.
- **`win32-arm64` is published without a kernel.** No runner produces that kernel yet, but the target is published anyway. Positron's bootstrap appends `?targetPlatform=<target>` to the gallery asset URL and a target that was never published answers HTTP 403, not the universal build — so an absent `win32-arm64` fails Positron's own Windows arm64 build rather than degrading to universal. Publishing the target with no kernel answers 200, and the extension falls back to a host-installed kernel there. It gains a real kernel later with no change on the Positron side. See posit-dev/positron#14954.
- **`universal` is not a fallback for any target.** The gallery matches `targetPlatform` exactly, in both directions: a universal build does not answer a targeted request, and targeted builds do not answer an untargeted one. `universal` exists for clients that ask without a target at all.

Watch mode for development: `npm run watch` (runs esbuild + tsc in parallel).

Expand Down