Skip to content
Merged
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
123 changes: 38 additions & 85 deletions .github/workflows/zed-e2e.yml
Original file line number Diff line number Diff line change
@@ -1,98 +1,51 @@
name: zed e2e (node + docker)

on:
pull_request:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
ZED_INTERFACES_REF: 61f654d5e4ca718abc4a280a641472466689c278
ZED_CLI_REF: 359ea72e21027ed54a29fad95b05f38a1ea142c3
NODE_LIB_REF: 2d41e658a382fdff27ef87a0db24dbaff280a685

jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v4

- name: Prepare the Docker build context
run: |
mkdir -p "$RUNNER_TEMP/zed-docker-context"
git clone --depth 1 \
https://github.com/zed-pkg/zed-interfaces \
"$RUNNER_TEMP/zed-docker-context/zed-interfaces"
git clone --depth 1 \
https://github.com/zed-pkg/zed-cli \
"$RUNNER_TEMP/zed-docker-context/zed-cli"

- name: Build Node + zed test image
run: |
docker build \
--file .github/docker/Dockerfile \
--tag zed-pkg-test/node-e2e \
"$RUNNER_TEMP/zed-docker-context"

- name: Publish node-lib inside Docker
run: |
git clone --depth 1 \
https://github.com/zed-pkg-test/node-lib \
"$RUNNER_TEMP/node-lib"
mkdir -p "$RUNNER_TEMP/zed-registry" "$RUNNER_TEMP/zed-home"
docker run --rm \
--volume "$RUNNER_TEMP/node-lib:/package" \
--volume "$RUNNER_TEMP/zed-registry:/registry" \
--workdir /package \
zed-pkg-test/node-e2e \
zed publish --registry file:///registry --skip-vcs-checks
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false

- name: Symlink install works with its store mounted
run: |
docker run --rm \
--volume "$GITHUB_WORKSPACE:/work" \
--volume "$RUNNER_TEMP/zed-registry:/registry:ro" \
--volume "$RUNNER_TEMP/zed-home:/zed-home" \
--workdir /work \
zed-pkg-test/node-e2e \
sh -euc '
zed install \
--registry file:///registry \
--home /zed-home \
--install-mode symlink
test -L .vendor/.zed/zed-pkg-test/node-lib
test -L node_modules/@zed-pkg-test/node-lib
node src/main.js
'
- name: Validate workflow
uses: docker://rhysd/actionlint@sha256:b1934ee5f1c509618f2508e6eb47ee0d3520686341fec936f3b79331f9315667
with:
args: .github/workflows/zed-e2e.yml

- name: Symlink install fails without its store mount
run: |
if docker run --rm \
--volume "$GITHUB_WORKSPACE:/work:ro" \
--workdir /work \
node:22-bookworm-slim \
node src/main.js
then
echo "expected the unmounted store-backed symlinks to fail"
exit 1
fi

- name: Frozen copy install contains no store symlinks
run: |
docker run --rm \
--volume "$GITHUB_WORKSPACE:/work" \
--volume "$RUNNER_TEMP/zed-registry:/registry:ro" \
--volume "$RUNNER_TEMP/zed-home:/zed-home" \
--workdir /work \
zed-pkg-test/node-e2e \
sh -euc '
zed install \
--frozen \
--registry file:///registry \
--home /zed-home \
--install-mode copy
test ! -L .vendor/.zed/zed-pkg-test/node-lib
test ! -L node_modules/@zed-pkg-test/node-lib
test -z "$(find .vendor/.zed node_modules/@zed-pkg-test -type l -print -quit)"
node src/main.js
'
- name: Validate executable test script
run: bash -n scripts/zed-e2e.sh

- name: Copy install runs in a fresh Node container
- name: Run pinned cross-container interoperability suite
shell: bash
run: |
docker run --rm \
--volume "$GITHUB_WORKSPACE:/work:ro" \
--workdir /work \
node:22-bookworm-slim \
node src/main.js
set -o pipefail
bash scripts/zed-e2e.sh 2>&1 | tee "$RUNNER_TEMP/zed-node-e2e.log"

- name: Upload interoperability diagnostics
if: ${{ always() }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: zed-node-e2e-log
path: ${{ runner.temp }}/zed-node-e2e.log
if-no-files-found: warn
retention-days: 7
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
"name": "node-app",
"version": "0.1.0",
"private": true,
"description": "npm still owns these; zed provides @zed-pkg-test/node-lib",
"description": "npm still owns ordinary dependencies; zed provides @zed-pkg-test/node-lib.",
"scripts": {
"check": "node --check src/main.js",
"start": "node src/main.js"
},
"license": "MIT",
"devDependencies": {}
}
175 changes: 175 additions & 0 deletions scripts/zed-e2e.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
#!/usr/bin/env bash
set -euo pipefail

: "${ZED_INTERFACES_REF:?ZED_INTERFACES_REF is required}"
: "${ZED_CLI_REF:?ZED_CLI_REF is required}"
: "${NODE_LIB_REF:?NODE_LIB_REF is required}"

WORKSPACE="${GITHUB_WORKSPACE:-$(pwd)}"
TEMP_ROOT="${RUNNER_TEMP:-${TMPDIR:-/tmp}/zed-pkg-test-node}"
RUN_ID="${GITHUB_SHA:-local}"
CONTEXT="$TEMP_ROOT/zed-docker-context"
REGISTRY="$TEMP_ROOT/zed-registry"
HOME_DIR="$TEMP_ROOT/zed-home"
NODE_LIB="$TEMP_ROOT/node-lib"
IMAGE="zed-pkg-test/node-e2e:$RUN_ID"

clone_at() {
local repo="$1"
local ref="$2"
local destination="$3"
git init -q "$destination"
git -C "$destination" remote add origin "$repo"
git -C "$destination" fetch --depth 1 origin "$ref"
git -C "$destination" checkout -q --detach FETCH_HEAD
test "$(git -C "$destination" rev-parse HEAD)" = "$ref"
}

prepare() {
rm -rf "$CONTEXT" "$REGISTRY" "$HOME_DIR" "$NODE_LIB"
mkdir -p "$CONTEXT" "$REGISTRY" "$HOME_DIR"
cd "$WORKSPACE"

docker run --rm \
--volume "$WORKSPACE:/work:ro" \
--workdir /work \
node:22-bookworm-slim \
npm run check

python3 - <<'PY'
import json
import tomllib
from pathlib import Path

native = json.loads(Path("package.json").read_text())
with Path(".zpkg.toml").open("rb") as handle:
zed = tomllib.load(handle)
package = zed["package"]
assert native["name"] == package["name"]
assert native["version"] == package["version"]
assert native["license"] == package["license"]
assert package["org"] == "zed-pkg-test"
assert zed["dependencies"] == {"zed-pkg-test/node-lib": "^1.0.0"}
PY

clone_at https://github.com/zed-pkg/zed-interfaces.git \
"$ZED_INTERFACES_REF" "$CONTEXT/zed-interfaces"
clone_at https://github.com/zed-pkg/zed-cli.git \
"$ZED_CLI_REF" "$CONTEXT/zed-cli"

docker build \
--file "$WORKSPACE/.github/docker/Dockerfile" \
--tag "$IMAGE" \
"$CONTEXT"

clone_at https://github.com/zed-pkg-test/node-lib.git \
"$NODE_LIB_REF" "$NODE_LIB"

docker run --rm \
--volume "$NODE_LIB:/package:ro" \
--workdir /package \
node:22-bookworm-slim \
node -e 'const {greet}=require("./src"); if(greet("fixture")!=="hello fixture from @zed-pkg-test/node-lib") process.exit(1)'

test -z "$(git -C "$NODE_LIB" status --porcelain)"
docker run --rm \
--volume "$NODE_LIB:/source:ro" \
--volume "$REGISTRY:/registry" \
--workdir /tmp \
"$IMAGE" \
sh -euc '
cp -a /source /tmp/package
chmod -R u+w /tmp/package
cd /tmp/package
zed publish --registry file:///registry --skip-vcs-checks
'
test -z "$(git -C "$NODE_LIB" status --porcelain)"
test "$(git -C "$NODE_LIB" rev-parse HEAD)" = "$NODE_LIB_REF"
if ! find "$REGISTRY" -type f -print -quit | grep -q .; then
echo "zed publish produced no registry artifact" >&2
exit 1
fi
}

symlink_install() {
cd "$WORKSPACE"
rm -rf .vendor/.zed node_modules .zed
docker run --rm \
--volume "$WORKSPACE:/work" \
--volume "$REGISTRY:/registry:ro" \
--volume "$HOME_DIR:/zed-home" \
--workdir /work \
"$IMAGE" \
sh -euc '
zed install \
--registry file:///registry \
--home /zed-home \
--install-mode symlink
test -L .vendor/.zed/zed-pkg-test/node-lib
test -L node_modules/@zed-pkg-test/node-lib
npm start
'
}

missing_store() {
cd "$WORKSPACE"
if docker run --rm \
--volume "$WORKSPACE:/work:ro" \
--workdir /work \
node:22-bookworm-slim \
npm start
then
echo "expected the unmounted store-backed symlinks to fail" >&2
exit 1
fi
}

copy_install() {
cd "$WORKSPACE"
docker run --rm \
--volume "$WORKSPACE:/work" \
--volume "$REGISTRY:/registry:ro" \
--volume "$HOME_DIR:/zed-home" \
--workdir /work \
"$IMAGE" \
sh -euc '
zed install \
--frozen \
--registry file:///registry \
--home /zed-home \
--install-mode copy
test ! -L .vendor/.zed/zed-pkg-test/node-lib
test ! -L node_modules/@zed-pkg-test/node-lib
test -z "$(find .vendor/.zed node_modules/@zed-pkg-test -type l -print -quit)"
npm start
'
}

fresh_copy() {
cd "$WORKSPACE"
docker run --rm \
--volume "$WORKSPACE:/work:ro" \
--workdir /work \
node:22-bookworm-slim \
npm start
}

phase="${1:-all}"
case "$phase" in
prepare) prepare ;;
symlink) symlink_install ;;
missing-store) missing_store ;;
copy) copy_install ;;
fresh-copy) fresh_copy ;;
all)
prepare
symlink_install
missing_store
copy_install
fresh_copy
;;
*)
echo "unknown phase: $phase" >&2
exit 2
;;
esac
Loading