mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-11-15 19:30:38 +08:00
Build Docker e2e and desktop releases from the workspace root
This commit is contained in:
@@ -16,6 +16,8 @@ set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
# The npm workspace that holds desktop and the shared UI code.
|
||||
REPO_DIR="$(cd "$PROJECT_DIR/.." && pwd)"
|
||||
|
||||
# ---- Flags ----
|
||||
|
||||
@@ -65,8 +67,9 @@ ensure_image() {
|
||||
VERSION="$(jq -r '.version' "$PROJECT_DIR/crates/radicle-tauri/tauri.conf.json")"
|
||||
RELEASE_SHA="$(git -C "$PROJECT_DIR" rev-parse HEAD)"
|
||||
SHORT_SHA="$(git -C "$PROJECT_DIR" rev-parse --short=8 HEAD)"
|
||||
# The Linux containers only mount desktop/, which has no .git of its own, so
|
||||
# build.rs can't ask git for the commit. Pass it in the way build.rs would get it.
|
||||
# git in the Linux containers may refuse the bind-mounted checkout, which the
|
||||
# container's root doesn't own, so build.rs can't rely on asking it for the
|
||||
# commit. Pass it in the way build.rs would get it.
|
||||
GIT_HEAD="$(git -C "$PROJECT_DIR" rev-parse --short HEAD)"
|
||||
RELEASE_DIR="$PROJECT_DIR/releases/v$VERSION"
|
||||
|
||||
@@ -93,8 +96,10 @@ fi
|
||||
if [[ "$CLEAN" == true ]]; then
|
||||
step "Cleaning build artifacts"
|
||||
rm -rf "$PROJECT_DIR/target-release"
|
||||
rm -rf "$PROJECT_DIR/node_modules"
|
||||
podman volume rm radicle-desktop-linux-target radicle-desktop-linux-nm radicle-desktop-linux-cargo 2>/dev/null || true
|
||||
rm -rf "$REPO_DIR/node_modules" "$REPO_DIR"/{explorer,desktop,shared/ui}/node_modules
|
||||
podman volume rm radicle-desktop-linux-target radicle-desktop-linux-cargo \
|
||||
radicle-desktop-linux-nm radicle-desktop-linux-nm-explorer \
|
||||
radicle-desktop-linux-nm-desktop radicle-desktop-linux-nm-shared 2>/dev/null || true
|
||||
podman image rm radicle-desktop-release-builder 2>/dev/null || true
|
||||
echo " Cleaned"
|
||||
fi
|
||||
@@ -103,8 +108,9 @@ fi
|
||||
|
||||
if [[ "$BUILD_DMG" == true ]]; then
|
||||
step "Building macOS aarch64 DMG"
|
||||
cd "$REPO_DIR"
|
||||
npm install -w desktop
|
||||
cd "$PROJECT_DIR"
|
||||
npm install
|
||||
CARGO_TARGET_DIR="$PROJECT_DIR/target-release" \
|
||||
npm exec -- tauri build --bundles dmg
|
||||
cp "target-release/release/bundle/dmg/Radicle_${VERSION}_aarch64.dmg" \
|
||||
@@ -122,24 +128,32 @@ fi
|
||||
# After a Rust toolchain bump or dependency change that confuses incremental
|
||||
# compilation: podman volume rm radicle-desktop-linux-target radicle-desktop-linux-cargo
|
||||
# After a major npm dependency change: podman volume rm radicle-desktop-linux-nm
|
||||
# radicle-desktop-linux-nm-explorer radicle-desktop-linux-nm-desktop
|
||||
# radicle-desktop-linux-nm-shared
|
||||
#
|
||||
# Every workspace package's node_modules is a volume, so that npm inside the
|
||||
# container never writes Linux builds into the host's checkout.
|
||||
|
||||
if [[ "$BUILD_DEB" == true ]]; then
|
||||
step "Building Linux amd64 deb"
|
||||
ensure_image "radicle-desktop-release-builder" "Dockerfile.release" "linux/arm64"
|
||||
|
||||
podman run --rm \
|
||||
-v "$PROJECT_DIR:/workspace:z" \
|
||||
-v radicle-desktop-linux-target:/workspace/target:z \
|
||||
-v "$REPO_DIR:/workspace:z" \
|
||||
-v radicle-desktop-linux-target:/workspace/desktop/target:z \
|
||||
-v radicle-desktop-linux-nm:/workspace/node_modules:z \
|
||||
-v radicle-desktop-linux-nm-explorer:/workspace/explorer/node_modules:z \
|
||||
-v radicle-desktop-linux-nm-desktop:/workspace/desktop/node_modules:z \
|
||||
-v radicle-desktop-linux-nm-shared:/workspace/shared/ui/node_modules:z \
|
||||
-v radicle-desktop-linux-cargo:/root/.cargo/registry:z \
|
||||
-v "$RELEASE_DIR:/output:z" \
|
||||
-w /workspace \
|
||||
-w /workspace/desktop \
|
||||
-e CI=true \
|
||||
-e GIT_HEAD="$GIT_HEAD" \
|
||||
radicle-desktop-release-builder \
|
||||
bash -c "
|
||||
set -euo pipefail
|
||||
npm ci
|
||||
(cd /workspace && npm ci -w desktop)
|
||||
npm exec -- tauri build --target x86_64-unknown-linux-gnu --bundles deb
|
||||
cp \"target/x86_64-unknown-linux-gnu/release/bundle/deb/radicle-desktop_${VERSION}_amd64.deb\" /output/
|
||||
"
|
||||
@@ -162,16 +176,19 @@ if [[ "$BUILD_APPIMAGE" == true ]]; then
|
||||
|
||||
podman run --rm \
|
||||
--privileged \
|
||||
-v "$PROJECT_DIR:/workspace:z" \
|
||||
-v radicle-desktop-linux-target:/workspace/target:z \
|
||||
-v "$REPO_DIR:/workspace:z" \
|
||||
-v radicle-desktop-linux-target:/workspace/desktop/target:z \
|
||||
-v radicle-desktop-linux-nm:/workspace/node_modules:z \
|
||||
-v radicle-desktop-linux-nm-explorer:/workspace/explorer/node_modules:z \
|
||||
-v radicle-desktop-linux-nm-desktop:/workspace/desktop/node_modules:z \
|
||||
-v radicle-desktop-linux-nm-shared:/workspace/shared/ui/node_modules:z \
|
||||
-v radicle-desktop-linux-cargo:/root/.cargo/registry:z \
|
||||
-v "$RELEASE_DIR:/output:z" \
|
||||
-w /workspace \
|
||||
-w /workspace/desktop \
|
||||
-e CI=true \
|
||||
-e GIT_HEAD="$GIT_HEAD" \
|
||||
radicle-desktop-release-builder \
|
||||
bash /workspace/scripts/appimage-build
|
||||
bash /workspace/desktop/scripts/appimage-build
|
||||
|
||||
# Strip the version so the filename matches what the website serves
|
||||
# (the DMG above is renamed the same way).
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
node_modules
|
||||
build
|
||||
.svelte-kit
|
||||
.git
|
||||
tests/tmp
|
||||
tests/artifacts
|
||||
tests/visual/snapshots
|
||||
data.ms
|
||||
dumps
|
||||
radicle-httpd/target
|
||||
radicle-search/target
|
||||
target
|
||||
.wrangler
|
||||
+11
-5
@@ -26,15 +26,21 @@ WORKDIR /work
|
||||
# Install Chromium plus its apt-level runtime dependencies, pinned to the
|
||||
# Playwright version in package-lock.json so the baked browser matches the
|
||||
# @playwright/test that npm ci installs into the volume at runtime. Copying
|
||||
# only the lockfiles keeps this layer cached across source changes.
|
||||
# only the npm manifests keeps this layer cached across source changes. The
|
||||
# build context is the repository root, which holds the npm workspace: npm ci
|
||||
# checks the lockfile against every workspace's package.json, even when it
|
||||
# installs only explorer.
|
||||
# --ignore-scripts: this layer only warms the browser cache, so dependency
|
||||
# install scripts are not necessary.
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci --ignore-scripts \
|
||||
COPY package.json package-lock.json .npmrc ./
|
||||
COPY shared/ui/package.json shared/ui/
|
||||
COPY explorer/package.json explorer/
|
||||
COPY desktop/package.json desktop/
|
||||
RUN npm ci -w explorer --ignore-scripts \
|
||||
&& npx playwright install --with-deps chromium \
|
||||
&& rm -rf node_modules
|
||||
&& rm -rf node_modules explorer/node_modules
|
||||
|
||||
ENTRYPOINT ["/work/scripts/docker-e2e-entrypoint.sh"]
|
||||
ENTRYPOINT ["/work/explorer/scripts/docker-e2e-entrypoint.sh"]
|
||||
|
||||
# --- local stage: adds Rust so the entrypoint can build radicle-httpd ---
|
||||
FROM base AS local
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
# The build context is the repository root, and the image only copies the npm
|
||||
# manifests: the repository itself is bind-mounted at runtime.
|
||||
*
|
||||
!package.json
|
||||
!package-lock.json
|
||||
!.npmrc
|
||||
!shared/ui/package.json
|
||||
!explorer/package.json
|
||||
!desktop/package.json
|
||||
@@ -1,6 +1,6 @@
|
||||
x-e2e-common: &e2e-common
|
||||
init: true
|
||||
working_dir: /work
|
||||
working_dir: /work/explorer
|
||||
environment:
|
||||
PLAYWRIGHT_BROWSERS_PATH: /ms-playwright
|
||||
|
||||
@@ -9,35 +9,53 @@ services:
|
||||
e2e:
|
||||
<<: *e2e-common
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.e2e
|
||||
# The repository root, which holds the npm workspace.
|
||||
context: ..
|
||||
dockerfile: explorer/Dockerfile.e2e
|
||||
target: base
|
||||
volumes:
|
||||
# Repo bind-mounted so code edits, test artifacts, and the
|
||||
# binary/fixture cache (tests/tmp) are shared with the host.
|
||||
- .:/work
|
||||
# Container-private node_modules: keeps the host's untouched and
|
||||
# avoids a glibc mismatch with host-built native modules.
|
||||
# Repo bind-mounted so code edits and test artifacts are shared with the
|
||||
# host.
|
||||
- ..:/work
|
||||
# Container-private node_modules for every workspace package: keeps the
|
||||
# host's untouched and avoids a glibc mismatch with host-built native
|
||||
# modules. npm hoists most packages to the root and nests the rest under
|
||||
# the package that needs them.
|
||||
- e2e-node-modules:/work/node_modules
|
||||
- e2e-explorer-node-modules:/work/explorer/node_modules
|
||||
- e2e-desktop-node-modules:/work/desktop/node_modules
|
||||
- e2e-shared-node-modules:/work/shared/ui/node_modules
|
||||
# Container-private binaries and fixtures: the host's binaries may be
|
||||
# built for another OS, and Radicle storage has to live on the
|
||||
# container's own filesystem rather than a bind mount from a macOS host.
|
||||
- e2e-tmp:/work/explorer/tests/tmp
|
||||
|
||||
# Compiles radicle-httpd from source and runs the suite against it.
|
||||
# Used via `scripts/test-e2e-docker --local` when testing backend changes.
|
||||
e2e-local:
|
||||
<<: *e2e-common
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.e2e
|
||||
context: ..
|
||||
dockerfile: explorer/Dockerfile.e2e
|
||||
target: local
|
||||
volumes:
|
||||
- .:/work
|
||||
- ..:/work
|
||||
- e2e-node-modules:/work/node_modules
|
||||
- e2e-explorer-node-modules:/work/explorer/node_modules
|
||||
- e2e-desktop-node-modules:/work/desktop/node_modules
|
||||
- e2e-shared-node-modules:/work/shared/ui/node_modules
|
||||
- e2e-tmp:/work/explorer/tests/tmp
|
||||
# Container-private cargo crate cache and workspace build dir, so the
|
||||
# Rust build is incremental across runs and never mixes with the
|
||||
# host's (different glibc/rustc) target artifacts.
|
||||
- e2e-cargo-registry:/usr/local/cargo/registry
|
||||
- e2e-httpd-target:/work/target
|
||||
- e2e-httpd-target:/work/explorer/target
|
||||
|
||||
volumes:
|
||||
e2e-node-modules:
|
||||
e2e-explorer-node-modules:
|
||||
e2e-desktop-node-modules:
|
||||
e2e-shared-node-modules:
|
||||
e2e-tmp:
|
||||
e2e-cargo-registry:
|
||||
e2e-httpd-target:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
# Entrypoint for the e2e Docker container. Installs npm deps into the
|
||||
# container-private node_modules volume (only when package-lock.json changes),
|
||||
# container-private node_modules volumes (only when the workspace's
|
||||
# package-lock.json changes),
|
||||
# ensures the Radicle test binaries are present, then runs Playwright. Any
|
||||
# arguments are forwarded to the test command.
|
||||
#
|
||||
@@ -8,7 +9,7 @@
|
||||
# source and tests the frontend against it) instead of test:e2e.
|
||||
set -euo pipefail
|
||||
|
||||
cd /work
|
||||
cd /work/explorer
|
||||
|
||||
# The container runs as root, so anything it writes into the bind-mounted repo
|
||||
# would otherwise be root-owned on the host. Hand those paths back to the
|
||||
@@ -23,11 +24,11 @@ cleanup() {
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
LOCK_HASH=$(md5sum package-lock.json | cut -d' ' -f1)
|
||||
STAMP=node_modules/.lockhash
|
||||
LOCK_HASH=$(md5sum ../package-lock.json | cut -d' ' -f1)
|
||||
STAMP=../node_modules/.lockhash
|
||||
if [ ! -f "$STAMP" ] || [ "$(cat "$STAMP")" != "$LOCK_HASH" ]; then
|
||||
echo "📦 Installing npm dependencies..."
|
||||
npm ci
|
||||
(cd .. && npm ci -w explorer)
|
||||
echo "$LOCK_HASH" >"$STAMP"
|
||||
else
|
||||
echo "📦 npm dependencies up to date."
|
||||
|
||||
Reference in New Issue
Block a user