first pass of merging in warp (doesn't build)
This commit is contained in:
+166
-4
@@ -1,13 +1,175 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
# Bootstrap dispatches to the platform-specific install scripts. Each step
|
||||
# that needs root sources `script/warp_sudo` and asks for confirmation
|
||||
# before running. Pass -y / --yes (or set WARP_SKIP_SUDO_PROMPT=1) to skip
|
||||
# the prompts in unattended environments.
|
||||
|
||||
OS_TYPE="$(uname -s)"
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. && pwd)"
|
||||
INSTALL_COMMON_SKILLS=1
|
||||
COMMON_SKILLS_TARGET="${WARP_COMMON_SKILLS_INSTALL_TARGET:-}"
|
||||
PLATFORM_ARGS=()
|
||||
|
||||
cd "${REPO_ROOT}"
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: ./script/bootstrap [options]
|
||||
|
||||
Prepare this checkout for Warp development by running the platform-specific bootstrap steps.
|
||||
|
||||
Options:
|
||||
-h, --help Show this help message.
|
||||
--install-common-skills Install or update common agent skills from skills-lock.json (default).
|
||||
--install-common-skills-in-repo
|
||||
Install or update common agent skills in this checkout's .agents/skills.
|
||||
--install-common-skills-globally
|
||||
Install or update common agent skills in ~/.agents/skills.
|
||||
--skip-common-skills Skip installing common agent skills.
|
||||
|
||||
Environment:
|
||||
WARP_SKIP_COMMON_SKILLS_INSTALL=1
|
||||
Skip installing common agent skills, even when --install-common-skills is provided.
|
||||
WARP_COMMON_SKILLS_INSTALL_TARGET=project|global
|
||||
Choose the install target when no explicit prompt answer is provided.
|
||||
Target prompting and duplicate checks are delegated to
|
||||
warpdotdev/common-skills/scripts/install_common_skills.
|
||||
WARP_COMMON_SKILLS_SCRIPTS_DIR=/path/to/common-skills/scripts
|
||||
Override where common-skills management scripts are loaded from.
|
||||
If unset, ./script/resolve_common_skills executes the raw script from
|
||||
warpdotdev/common-skills.
|
||||
WARP_COMMON_SKILLS_REF=<git-ref>
|
||||
Override the remote warpdotdev/common-skills ref for raw script fallback.
|
||||
EOF
|
||||
}
|
||||
|
||||
print_bootstrap_preview() {
|
||||
local platform="$1"
|
||||
|
||||
echo "Warp bootstrap is starting for ${platform}."
|
||||
echo "It will:"
|
||||
|
||||
if [[ "${platform}" = "macOS" ]]; then
|
||||
echo " - Configure Xcode as the active developer directory."
|
||||
echo " - Install or update Cargo, Homebrew, PowerShell, Docker, gcloud, and related development tools."
|
||||
echo " - Add the aarch64-apple-darwin Rust target."
|
||||
elif [[ "${platform}" = "Linux" ]]; then
|
||||
echo " - Update apt package metadata."
|
||||
echo " - Install dependencies needed to build, run, and test Warp."
|
||||
echo " - Install linuxdeploy and check gcloud authentication."
|
||||
fi
|
||||
|
||||
if [[ "${INSTALL_COMMON_SKILLS}" -eq 0 ]]; then
|
||||
echo " - Skip common agent skills because --skip-common-skills was provided."
|
||||
elif [[ "${WARP_SKIP_COMMON_SKILLS_INSTALL:-}" = "1" ]]; then
|
||||
echo " - Skip common agent skills because WARP_SKIP_COMMON_SKILLS_INSTALL=1."
|
||||
elif [[ "${COMMON_SKILLS_TARGET}" = "global" ]]; then
|
||||
echo " - Install or update common agent skills in ~/.agents/skills if needed."
|
||||
elif [[ "${COMMON_SKILLS_TARGET}" = "project" ]]; then
|
||||
echo " - Install or update common agent skills in this checkout's .agents/skills if needed."
|
||||
else
|
||||
echo " - Prompt for where common agent skills should be installed before installing or updating them."
|
||||
fi
|
||||
if [[ "${INSTALL_COMMON_SKILLS}" -eq 1 && "${WARP_SKIP_COMMON_SKILLS_INSTALL:-}" != "1" ]]; then
|
||||
echo " - Verify installed common skills match skills-lock.json."
|
||||
fi
|
||||
echo "Run ./script/bootstrap --help to see options and environment overrides."
|
||||
echo
|
||||
}
|
||||
|
||||
|
||||
for arg in "$@"; do
|
||||
case "${arg}" in
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
-y|--yes)
|
||||
export WARP_SKIP_SUDO_PROMPT=1
|
||||
if [[ ! "$OS_TYPE" =~ ^(MINGW64_NT|MSYS_NT) ]]; then
|
||||
PLATFORM_ARGS+=("${arg}")
|
||||
fi
|
||||
;;
|
||||
--install-common-skills)
|
||||
INSTALL_COMMON_SKILLS=1
|
||||
;;
|
||||
--install-common-skills-in-repo)
|
||||
INSTALL_COMMON_SKILLS=1
|
||||
COMMON_SKILLS_TARGET="project"
|
||||
;;
|
||||
--install-common-skills-globally)
|
||||
INSTALL_COMMON_SKILLS=1
|
||||
COMMON_SKILLS_TARGET="global"
|
||||
;;
|
||||
--skip-common-skills)
|
||||
INSTALL_COMMON_SKILLS=0
|
||||
;;
|
||||
*)
|
||||
PLATFORM_ARGS+=("${arg}")
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
maybe_install_common_skills() {
|
||||
if [[ "${INSTALL_COMMON_SKILLS}" -eq 1 ]]; then
|
||||
local target_args=()
|
||||
if [[ "${WARP_SKIP_COMMON_SKILLS_INSTALL:-}" = "1" ]]; then
|
||||
return
|
||||
fi
|
||||
if [[ "${COMMON_SKILLS_TARGET}" = "project" || "${COMMON_SKILLS_TARGET}" = "global" ]]; then
|
||||
target_args=("--${COMMON_SKILLS_TARGET}")
|
||||
if ! ./script/resolve_common_skills install_common_skills -- --repo-root "${REPO_ROOT}" "${target_args[@]}" --if-needed; then
|
||||
echo "error: unable to install common skills; continuing without them." >&2
|
||||
fi
|
||||
else
|
||||
if ! ./script/resolve_common_skills install_common_skills -- --repo-root "${REPO_ROOT}" --if-needed --prompt-for-target; then
|
||||
echo "error: unable to install common skills; continuing without them." >&2
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# This repository requires Git LFS; ensure it is installed and initialized
|
||||
# for this checkout.
|
||||
ensure_git_lfs() {
|
||||
if ! command -v git-lfs >/dev/null 2>&1; then
|
||||
echo
|
||||
echo "warning: git-lfs is not installed. Install it before continuing:"
|
||||
case "${OS_TYPE}" in
|
||||
Darwin) echo " brew install git-lfs" ;;
|
||||
Linux) echo " sudo apt-get install -y git-lfs # or your distro's package manager" ;;
|
||||
MINGW64_NT*|MSYS_NT*) echo " choco install git-lfs # or: winget install GitHub.GitLFS" ;;
|
||||
*) echo " See https://git-lfs.com for install instructions." ;;
|
||||
esac
|
||||
echo "After installing, re-run ./script/bootstrap."
|
||||
return 1
|
||||
fi
|
||||
git lfs install --local >/dev/null
|
||||
git lfs pull
|
||||
}
|
||||
|
||||
ensure_git_lfs
|
||||
|
||||
if [[ "$OS_TYPE" = "Darwin" ]]; then
|
||||
./script/macos/bootstrap "$@"
|
||||
print_bootstrap_preview "macOS"
|
||||
./script/macos/bootstrap "${PLATFORM_ARGS[@]}"
|
||||
maybe_install_common_skills
|
||||
elif [[ "$OS_TYPE" = "Linux" ]]; then
|
||||
./script/linux/bootstrap "$@"
|
||||
elif [[ "$OS_TYPE" =~ ^[MINGW64_NT|MSYS_NT] ]]; then
|
||||
./script/windows/bootstrap.ps1 "$@"
|
||||
print_bootstrap_preview "Linux"
|
||||
./script/linux/bootstrap "${PLATFORM_ARGS[@]}"
|
||||
maybe_install_common_skills
|
||||
elif [[ "$OS_TYPE" =~ ^(MINGW64_NT|MSYS_NT) ]]; then
|
||||
if [[ "${INSTALL_COMMON_SKILLS}" -eq 1 ]]; then
|
||||
if [[ -n "${COMMON_SKILLS_TARGET}" ]]; then
|
||||
./script/windows/bootstrap.ps1 "${PLATFORM_ARGS[@]}" -InstallCommonSkills -CommonSkillsTarget "${COMMON_SKILLS_TARGET}"
|
||||
else
|
||||
./script/windows/bootstrap.ps1 "${PLATFORM_ARGS[@]}" -InstallCommonSkills
|
||||
fi
|
||||
else
|
||||
./script/windows/bootstrap.ps1 "${PLATFORM_ARGS[@]}"
|
||||
fi
|
||||
else
|
||||
echo "No bootstrap script defined for the current platform!"
|
||||
exit 1
|
||||
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
matches=$(
|
||||
find . \
|
||||
\( -path './.git' -o -path './target' \) -prune -o \
|
||||
-type f \
|
||||
-name '*.rs' \
|
||||
-exec grep -nE '^[[:space:]]*mod[[:space:]]+tests[[:space:]]*\{' {} + || true
|
||||
)
|
||||
|
||||
if [[ -z "$matches" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
cat <<'EOF'
|
||||
Inline Rust test modules are not allowed. Move test code into a sibling `_tests.rs`
|
||||
file and include it from the original module like this:
|
||||
|
||||
```
|
||||
#[cfg(test)]
|
||||
#[path = "..._tests.rs"]
|
||||
mod tests;
|
||||
```
|
||||
|
||||
EOF
|
||||
while IFS= read -r match; do
|
||||
file=${match%%:*}
|
||||
rest=${match#*:}
|
||||
line=${rest%%:*}
|
||||
|
||||
if [[ "${GITHUB_ACTIONS:-}" == "true" ]]; then
|
||||
echo "::error file=${file#./},line=$line::Move this inline test module to a sibling _tests.rs file."
|
||||
else
|
||||
echo "$match"
|
||||
fi
|
||||
done <<< "$matches"
|
||||
|
||||
exit 1
|
||||
@@ -13,7 +13,7 @@
|
||||
# Gating is progressive: earlier gates include all skills from later gates.
|
||||
# For example, a dogfood build includes skills from both dogfood/ and
|
||||
# preview/. The stable channel has no gate — stable-ready skills belong
|
||||
# in resources/skills/ (the always-bundled directory).
|
||||
# in resources/bundled/skills/ (the always-bundled directory).
|
||||
|
||||
set -e
|
||||
|
||||
@@ -35,10 +35,10 @@ if [ ! -d "$GATED_SKILLS_SRC" ]; then
|
||||
fi
|
||||
|
||||
# Error out if a stable/ gate directory exists — stable skills should live
|
||||
# in the always-bundled resources/skills/ directory instead.
|
||||
# in the always-bundled resources/bundled/skills/ directory instead.
|
||||
if [ -d "$GATED_SKILLS_SRC/stable" ]; then
|
||||
echo "Error: found a 'stable/' directory in $GATED_SKILLS_SRC." >&2
|
||||
echo "The stable channel does not use gated skills. Move stable-ready skills to resources/skills/ (the always-bundled directory) instead." >&2
|
||||
echo "The stable channel does not use gated skills. Move stable-ready skills to resources/bundled/skills/ (the always-bundled directory) instead." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -59,15 +59,16 @@ if [[ "$GIT_BRANCH_NAME" == "$RELEASE_BRANCH_PREFIX/"* ]]; then
|
||||
else
|
||||
# Creating release branch and new tag and version _00
|
||||
date_formatted=$(date +'%Y.%m.%d.%H.%M')
|
||||
tag="v0.$date_formatted.${CHANNEL}_00"
|
||||
echo >&2 "Creating tag $tag"
|
||||
git tag "$tag"
|
||||
git push origin "$tag"
|
||||
|
||||
release_branch_name="v0.$date_formatted.${CHANNEL}"
|
||||
echo >&2 "Creating release branch $RELEASE_BRANCH_PREFIX/$release_branch_name"
|
||||
git checkout -b "$RELEASE_BRANCH_PREFIX/$release_branch_name"
|
||||
git push -u origin "$RELEASE_BRANCH_PREFIX/$release_branch_name"
|
||||
|
||||
tag="v0.$date_formatted.${CHANNEL}_00"
|
||||
echo >&2 "Creating tag $tag"
|
||||
git tag "$tag"
|
||||
git push origin "$tag"
|
||||
echo "$tag"
|
||||
fi
|
||||
|
||||
|
||||
+66
-18
@@ -77,12 +77,8 @@ case "$PROFILE_MODE" in
|
||||
;;
|
||||
esac
|
||||
|
||||
# Check for musl-cross linker
|
||||
if ! command -v x86_64-linux-musl-gcc &>/dev/null; then
|
||||
echo "Error: x86_64-linux-musl-gcc not found." >&2
|
||||
echo "Install it with: brew install filosottile/musl-cross/musl-cross" >&2
|
||||
exit 1
|
||||
fi
|
||||
TARGET="x86_64-unknown-linux-musl"
|
||||
source "$SCRIPT_DIR/linux/configure_musl_toolchain" "$TARGET"
|
||||
|
||||
# Check for musl target
|
||||
if ! rustup target list --installed 2>/dev/null | grep -q x86_64-unknown-linux-musl; then
|
||||
@@ -91,9 +87,7 @@ if ! rustup target list --installed 2>/dev/null | grep -q x86_64-unknown-linux-m
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Determine build parameters
|
||||
TARGET="x86_64-unknown-linux-musl"
|
||||
|
||||
# Select the requested Cargo build profile.
|
||||
case "$PROFILE_MODE" in
|
||||
dev-remote)
|
||||
CARGO_PROFILE="dev-remote"
|
||||
@@ -109,10 +103,13 @@ case "$PROFILE_MODE" in
|
||||
;;
|
||||
esac
|
||||
|
||||
FEATURES="release_bundle,crash_reporting,standalone,agent_mode_debug"
|
||||
FEATURES="release_bundle,crash_reporting,standalone,agent_mode_debug,remote_codebase_indexing"
|
||||
WARP_BIN="warp"
|
||||
BINARY_NAME="oz-local"
|
||||
REMOTE_DIR=".warp-local/remote-server"
|
||||
# Global, version-independent resources location read by the daemon. Must
|
||||
# match BUNDLED_RESOURCES_DIR_NAME in crates/remote_server/src/setup.rs.
|
||||
BUNDLED_RESOURCES_DIR_NAME="bundled_resources"
|
||||
|
||||
# Determine the output directory
|
||||
CARGO_TARGET_DIR="${CARGO_TARGET_DIR:-$WORKSPACE_ROOT/target}"
|
||||
@@ -125,17 +122,14 @@ case "$CARGO_PROFILE" in
|
||||
;;
|
||||
esac
|
||||
BUILT_BINARY="$OUTPUT_DIR/$WARP_BIN"
|
||||
LOCAL_RESOURCES_DIR="$OUTPUT_DIR/remote-server-resources"
|
||||
|
||||
echo "==> Building Oz CLI for $TARGET (profile=$CARGO_PROFILE)"
|
||||
echo " Binary: $WARP_BIN -> $BINARY_NAME"
|
||||
echo " Features: $FEATURES"
|
||||
echo ""
|
||||
|
||||
# Build with linker and rustflags overrides to avoid macOS-specific flags
|
||||
# from .cargo/config.toml
|
||||
CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=x86_64-linux-musl-gcc \
|
||||
CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_RUSTFLAGS="-C symbol-mangling-version=v0" \
|
||||
cargo build \
|
||||
cargo build \
|
||||
-p warp \
|
||||
--bin "$WARP_BIN" \
|
||||
--target "$TARGET" \
|
||||
@@ -150,6 +144,13 @@ fi
|
||||
BINARY_SIZE=$(du -h "$BUILT_BINARY" | cut -f1)
|
||||
echo ""
|
||||
echo "==> Build complete ($BINARY_SIZE)"
|
||||
# Prepare the bundled resources tree (skills, settings schema) deployed to
|
||||
# the global, version-independent location the daemon reads.
|
||||
rm -rf "$LOCAL_RESOURCES_DIR"
|
||||
"$WORKSPACE_ROOT/script/prepare_bundled_resources" \
|
||||
"$LOCAL_RESOURCES_DIR" \
|
||||
local \
|
||||
"$CARGO_PROFILE"
|
||||
|
||||
# Resolve $HOME on the remote so our upload lands in the same directory the
|
||||
# Warp client checks. The client runs `test -x ~/.warp-local/...` and lets
|
||||
@@ -175,10 +176,10 @@ if ! ssh "$HOST" "command -v rsync" &>/dev/null; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# Ensure the remote directory exists
|
||||
# Ensure the remote install directory exists
|
||||
ssh "$HOST" "mkdir -p $REMOTE_ABS_DIR"
|
||||
|
||||
echo "==> Uploading to $HOST:$REMOTE_ABS_DIR/$BINARY_NAME"
|
||||
echo "==> Uploading binary to $HOST:$REMOTE_ABS_DIR/$BINARY_NAME"
|
||||
|
||||
# Upload via rsync with delta transfer and compression.
|
||||
# After the first deploy, only changed bytes are transferred.
|
||||
@@ -189,6 +190,53 @@ rsync -z -t --partial --progress \
|
||||
# Set executable permissions (done separately for openrsync compatibility on macOS)
|
||||
ssh "$HOST" "chmod 755 $REMOTE_ABS_DIR/$BINARY_NAME"
|
||||
|
||||
echo "==> Uploading bundled resources to $HOST:$REMOTE_ABS_DIR/$BUNDLED_RESOURCES_DIR_NAME"
|
||||
rsync -z -rlt --delete --partial --progress \
|
||||
"$LOCAL_RESOURCES_DIR/" \
|
||||
"$HOST:$REMOTE_ABS_DIR/$BUNDLED_RESOURCES_DIR_NAME/"
|
||||
|
||||
echo "==> Stopping stale remote-server daemons on $HOST"
|
||||
ssh "$HOST" bash <<'EOF'
|
||||
set -euo pipefail
|
||||
|
||||
REMOTE_SERVER_ROOT="$HOME/.warp-local/remote-server"
|
||||
shopt -s nullglob
|
||||
|
||||
for pid_file in "$REMOTE_SERVER_ROOT"/*/server.pid; do
|
||||
daemon_dir="$(dirname "$pid_file")"
|
||||
pid="$(cat "$pid_file" 2>/dev/null || true)"
|
||||
if [[ -z "$pid" || ! "$pid" =~ ^[0-9]+$ ]]; then
|
||||
rm -f "$daemon_dir/server.sock" "$pid_file"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ ! -r "/proc/$pid/cmdline" ]]; then
|
||||
rm -f "$daemon_dir/server.sock" "$pid_file"
|
||||
continue
|
||||
fi
|
||||
|
||||
cmdline="$(tr '\0' ' ' <"/proc/$pid/cmdline" || true)"
|
||||
if [[ "$cmdline" != *remote-server-daemon* ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
echo " Stopping stale daemon pid=$pid dir=$daemon_dir"
|
||||
kill "$pid" 2>/dev/null || true
|
||||
for _ in {1..50}; do
|
||||
if ! kill -0 "$pid" 2>/dev/null; then
|
||||
break
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
if kill -0 "$pid" 2>/dev/null; then
|
||||
echo " Force-stopping stale daemon pid=$pid"
|
||||
kill -9 "$pid" 2>/dev/null || true
|
||||
fi
|
||||
rm -f "$daemon_dir/server.sock" "$pid_file"
|
||||
done
|
||||
EOF
|
||||
|
||||
echo ""
|
||||
echo "==> Done! Binary deployed to $HOST:$REMOTE_ABS_DIR/$BINARY_NAME"
|
||||
echo " (resolved from ~/$REMOTE_DIR/$BINARY_NAME on remote)"
|
||||
echo " Bundled resources: $REMOTE_ABS_DIR/$BUNDLED_RESOURCES_DIR_NAME"
|
||||
echo " (resolved from ~/$REMOTE_DIR on remote)"
|
||||
|
||||
Executable
+206
@@ -0,0 +1,206 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Builds the Integration-channel Oz CLI for Linux x86_64 (musl) and uploads it
|
||||
# to the SSH integration testing VM so that remote-server integration tests run
|
||||
# against the binary built from the current branch.
|
||||
#
|
||||
# This script is intended to be run once by CI before the integration test
|
||||
# suite, not by individual test functions. The binary is placed at the
|
||||
# versioned Integration channel path on the remote host, which is where the
|
||||
# Integration channel's `check_binary` looks.
|
||||
#
|
||||
# Prerequisites (same as script/deploy_remote_server):
|
||||
# On Linux, install curl, sha256sum, tar, and sshpass.
|
||||
# rustup target add x86_64-unknown-linux-musl
|
||||
# gcloud CLI authenticated for the warp-ssh-integration-testing project
|
||||
#
|
||||
# Usage:
|
||||
# script/deploy_remote_server_to_test_vm
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
WORKSPACE_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
TARGET="x86_64-unknown-linux-musl"
|
||||
CARGO_PROFILE="dev-remote"
|
||||
FEATURES="crash_reporting,standalone,agent_mode_debug,remote_codebase_indexing"
|
||||
WARP_BIN="integration"
|
||||
# The integration test runner uses Channel::Integration, which maps to
|
||||
# cli_command_name() = "oz-integration", remote_server_dir() = "~/.warp-dev/remote-server",
|
||||
# and remote_server_binary() = "oz-integration-${pinned_version}".
|
||||
# See crates/warp_core/src/channel/mod.rs, crates/remote_server/src/setup.rs,
|
||||
# and crates/integration/src/bin/integration.rs.
|
||||
#
|
||||
# We intentionally build app/src/bin/integration.rs instead of the normal
|
||||
# Local-channel app binary. The Local-channel release bundle requires
|
||||
# warp-channel-config to generate local_config.json at compile time, but this CI
|
||||
# path should not depend on private channel config. The Integration-channel
|
||||
# binary embeds a static non-secret config instead.
|
||||
REMOTE_DIR=".warp-dev/remote-server"
|
||||
|
||||
# Dedicated remote-server test VM, configured similarly to the SSH integration
|
||||
# test VM but isolated from the general SSH integration suite.
|
||||
REMOTE_USERS=(bash zsh)
|
||||
REMOTE_HOST="ssh-remote-server-testing"
|
||||
REMOTE_PORT="22"
|
||||
PROXY_COMMAND="gcloud compute start-iap-tunnel ssh-remote-server-testing ${REMOTE_PORT} --listen-on-stdin --project=warp-ssh-integration-testing --zone=us-east4-b"
|
||||
|
||||
|
||||
app_version() {
|
||||
if [[ -n "${GIT_RELEASE_TAG:-}" ]]; then
|
||||
echo "$GIT_RELEASE_TAG"
|
||||
return
|
||||
fi
|
||||
|
||||
cargo metadata --no-deps --format-version 1 \
|
||||
| python3 -c 'import json, sys; print(next(p["version"] for p in json.load(sys.stdin)["packages"] if p["name"] == "remote_server" and p["manifest_path"].endswith("/crates/remote_server/Cargo.toml")))'
|
||||
}
|
||||
|
||||
# ── Preflight checks ──────────────────────────────────────────────
|
||||
source "$SCRIPT_DIR/linux/configure_musl_toolchain" "$TARGET"
|
||||
|
||||
if ! rustup target list --installed 2>/dev/null | grep -q "$TARGET"; then
|
||||
echo "Error: $TARGET target not installed." >&2
|
||||
echo "Install it with: rustup target add $TARGET" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BUNDLE_VERSION="$(app_version)"
|
||||
BUNDLE_BINARY_NAME="oz-integration"
|
||||
BINARY_NAME="$BUNDLE_BINARY_NAME-$BUNDLE_VERSION"
|
||||
|
||||
# ── Build ─────────────────────────────────────────────────────────
|
||||
|
||||
CARGO_TARGET_DIR="${CARGO_TARGET_DIR:-$WORKSPACE_ROOT/target}"
|
||||
OUTPUT_DIR="$CARGO_TARGET_DIR/$TARGET/$CARGO_PROFILE"
|
||||
BUILT_BINARY="$OUTPUT_DIR/$WARP_BIN"
|
||||
LOCAL_BUNDLE_DIR="$OUTPUT_DIR/remote-server-integration-bundle"
|
||||
LOCAL_BUNDLE_TARBALL="$OUTPUT_DIR/remote-server-integration-bundle.tar.gz"
|
||||
|
||||
echo "==> Building Integration-channel Oz CLI for $TARGET (profile=$CARGO_PROFILE)"
|
||||
|
||||
cargo build \
|
||||
-p warp \
|
||||
--bin "$WARP_BIN" \
|
||||
--target "$TARGET" \
|
||||
--profile "$CARGO_PROFILE" \
|
||||
--features "$FEATURES"
|
||||
|
||||
if [[ ! -f "$BUILT_BINARY" ]]; then
|
||||
echo "Error: Expected binary not found at $BUILT_BINARY" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BINARY_SIZE=$(du -h "$BUILT_BINARY" | cut -f1)
|
||||
echo "==> Build complete ($BINARY_SIZE)"
|
||||
|
||||
rm -rf "$LOCAL_BUNDLE_DIR"
|
||||
mkdir -p "$LOCAL_BUNDLE_DIR"
|
||||
cp "$BUILT_BINARY" "$LOCAL_BUNDLE_DIR/$BUNDLE_BINARY_NAME"
|
||||
"$WORKSPACE_ROOT/script/prepare_bundled_resources" \
|
||||
"$LOCAL_BUNDLE_DIR/resources" \
|
||||
integration \
|
||||
"$CARGO_PROFILE"
|
||||
tar -czf "$LOCAL_BUNDLE_TARBALL" -C "$LOCAL_BUNDLE_DIR" .
|
||||
|
||||
# ── Upload via SCP through GCP IAP tunnel ─────────────────────────
|
||||
# The test VM uses password auth (same as the SSH integration tests).
|
||||
# sshpass provides the password non-interactively for SSH/SCP.
|
||||
SSH_PASSWORD="password"
|
||||
SSH_OPTS=(-p "$REMOTE_PORT" -o "ProxyCommand=$PROXY_COMMAND" -o PreferredAuthentications=password -o PubkeyAuthentication=no -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null)
|
||||
|
||||
if command -v sshpass &>/dev/null; then
|
||||
export SSHPASS="$SSH_PASSWORD"
|
||||
SSH_CMD=(sshpass -e ssh)
|
||||
SCP_CMD=(sshpass -e scp)
|
||||
else
|
||||
echo "Warning: sshpass not found, SSH/SCP will prompt for password interactively." >&2
|
||||
if [[ "$(uname -s)" == "Darwin" ]]; then
|
||||
echo "Install it with: brew install hudochenkov/sshpass/sshpass" >&2
|
||||
elif [[ "$(uname -s)" == "Linux" ]]; then
|
||||
echo "Install it with: sudo apt-get install sshpass" >&2
|
||||
fi
|
||||
SSH_CMD=(ssh)
|
||||
SCP_CMD=(scp)
|
||||
fi
|
||||
|
||||
for REMOTE_USER in "${REMOTE_USERS[@]}"; do
|
||||
echo "==> Ensuring remote directory exists for ${REMOTE_USER}"
|
||||
"${SSH_CMD[@]}" "${SSH_OPTS[@]}" "${REMOTE_USER}@${REMOTE_HOST}" "mkdir -p ~/$REMOTE_DIR"
|
||||
echo "==> Stopping stale remote server daemons for ${REMOTE_USER}"
|
||||
"${SSH_CMD[@]}" "${SSH_OPTS[@]}" "${REMOTE_USER}@${REMOTE_HOST}" "bash -s -- '$REMOTE_DIR'" <<'REMOTE_SCRIPT'
|
||||
set -euo pipefail
|
||||
|
||||
REMOTE_ROOT="$HOME/$1"
|
||||
mkdir -p "$REMOTE_ROOT"
|
||||
|
||||
shopt -s nullglob
|
||||
for PID_FILE in "$REMOTE_ROOT"/*/server.pid; do
|
||||
DAEMON_DIR="$(dirname "$PID_FILE")"
|
||||
PID="$(cat "$PID_FILE" 2>/dev/null || true)"
|
||||
|
||||
if [[ "$PID" =~ ^[0-9]+$ ]] && [[ -d "/proc/$PID" ]]; then
|
||||
CMDLINE="$(tr '\0' ' ' < "/proc/$PID/cmdline" 2>/dev/null || true)"
|
||||
if [[ "$CMDLINE" == *remote-server-daemon* ]]; then
|
||||
echo "Stopping stale remote-server daemon pid $PID"
|
||||
kill "$PID" 2>/dev/null || true
|
||||
|
||||
for _ in {1..50}; do
|
||||
if ! kill -0 "$PID" 2>/dev/null; then
|
||||
break
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
if kill -0 "$PID" 2>/dev/null; then
|
||||
echo "Force-stopping stale remote-server daemon pid $PID"
|
||||
kill -9 "$PID" 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -f "$DAEMON_DIR/server.sock" "$DAEMON_DIR/server.pid"
|
||||
done
|
||||
|
||||
rm -f "$REMOTE_ROOT"/remote-server-integration-bundle-*.tar.gz
|
||||
REMOTE_SCRIPT
|
||||
|
||||
TMP_BUNDLE_NAME="remote-server-integration-bundle-${GITHUB_RUN_ID:-local}-$$-${REMOTE_USER}.tar.gz"
|
||||
echo "==> Uploading bundle to ${REMOTE_USER}@${REMOTE_HOST}:~/$REMOTE_DIR/$TMP_BUNDLE_NAME"
|
||||
"${SCP_CMD[@]}" -P "$REMOTE_PORT" \
|
||||
-o "ProxyCommand=$PROXY_COMMAND" \
|
||||
-o PreferredAuthentications=password \
|
||||
-o PubkeyAuthentication=no \
|
||||
-o StrictHostKeyChecking=no \
|
||||
-o UserKnownHostsFile=/dev/null \
|
||||
"$LOCAL_BUNDLE_TARBALL" \
|
||||
"${REMOTE_USER}@${REMOTE_HOST}:~/$REMOTE_DIR/$TMP_BUNDLE_NAME"
|
||||
|
||||
echo "==> Installing binary and resources for ${REMOTE_USER}"
|
||||
# Args: <remote dir> <tarball name> <binary name in tarball> <installed name>.
|
||||
# The tarball ships the unversioned binary beside its resources/ tree; the
|
||||
# installed binary carries the version suffix the Integration channel
|
||||
# launches. The resources tree lands at `bundled_resources`, the global
|
||||
# version-independent location the daemon reads (must match
|
||||
# BUNDLED_RESOURCES_DIR_NAME in crates/remote_server/src/setup.rs).
|
||||
"${SSH_CMD[@]}" "${SSH_OPTS[@]}" "${REMOTE_USER}@${REMOTE_HOST}" \
|
||||
"bash -s -- '$REMOTE_DIR' '$TMP_BUNDLE_NAME' '$BUNDLE_BINARY_NAME' '$BINARY_NAME'" <<'REMOTE_SCRIPT'
|
||||
set -euo pipefail
|
||||
|
||||
cd "$HOME/$1"
|
||||
tar -xzf "$2"
|
||||
rm -f "$2"
|
||||
|
||||
rm -rf bundled_resources
|
||||
mv resources bundled_resources
|
||||
|
||||
chmod 755 "$3"
|
||||
mv -f "$3" "$4"
|
||||
"./$4" --version
|
||||
REMOTE_SCRIPT
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "==> Done! Binary deployed to ${REMOTE_HOST}:~/$REMOTE_DIR/$BINARY_NAME for users: ${REMOTE_USERS[*]}"
|
||||
echo " Bundled resources: ~/$REMOTE_DIR/bundled_resources"
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script to format (Rust) code.
|
||||
|
||||
set -e
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
EXTRA_ARGS=()
|
||||
|
||||
while (( "$#" )); do
|
||||
case "$1" in
|
||||
--check)
|
||||
EXTRA_ARGS+=("--check")
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Format with specific configuration around how module imports are formatted.
|
||||
#
|
||||
# We need to set RUSTC_BOOTSTRAP to allow using unstable features on a stable toolchain.
|
||||
RUSTC_BOOTSTRAP=1 cargo fmt -- --config imports_granularity=Module --config group_imports=StdExternalCrate "${EXTRA_ARGS[@]}"
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
set -e
|
||||
|
||||
. "$PWD/script/warp_sudo"
|
||||
|
||||
# Update the apt cache before installing dependencies. It can be slow, so the install scripts
|
||||
# don't do it (to avoid doing it more than once).
|
||||
sudo apt update -y
|
||||
warp_sudo apt update -y
|
||||
|
||||
# Install all dependencies needed to build, run, and test Warp.
|
||||
"$PWD"/script/linux/install_test_deps
|
||||
|
||||
+74
-18
@@ -5,8 +5,6 @@
|
||||
set -e
|
||||
|
||||
WORKSPACE_ROOT_DIR="$(pwd)"
|
||||
CARGO_TARGET_DIR="${CARGO_TARGET_DIR:-$WORKSPACE_ROOT_DIR/target}"
|
||||
DIST_DIR="$CARGO_TARGET_DIR/dist"
|
||||
|
||||
cleanup() {
|
||||
# Delete the directory that was used as a staging area during the bundling
|
||||
@@ -22,6 +20,7 @@ trap cleanup EXIT
|
||||
# By default we build dev bundles.
|
||||
RELEASE_CHANNEL="dev"
|
||||
FEATURES="release_bundle,crash_reporting"
|
||||
EXTRA_FEATURES=""
|
||||
PACKAGES=( appimage )
|
||||
BUILD="true"
|
||||
BUILD_ARCH="$(uname -m)"
|
||||
@@ -75,10 +74,19 @@ while (( "$#" )); do
|
||||
PACKAGES=( $(IFS=, ; echo $2) )
|
||||
shift 2
|
||||
;;
|
||||
--features)
|
||||
if [ -n "$2" ] && [ "${2:0:1}" != "-" ]; then
|
||||
EXTRA_FEATURES="$2"
|
||||
shift 2
|
||||
else
|
||||
echo "Error: Argument for $1 is missing" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
--artifact)
|
||||
if [ -n "$2" ] && [ "${2:0:1}" != "-" ]; then
|
||||
if [[ "$2" != "app" && "$2" != "cli" ]]; then
|
||||
echo "Error: --artifact must be either 'app' or 'cli', got '$2'" >&2
|
||||
if [[ "$2" != "app" && "$2" != "cli" && "$2" != "warpctrl" ]]; then
|
||||
echo "Error: --artifact must be 'app', 'cli', or 'warpctrl', got '$2'" >&2
|
||||
exit 1
|
||||
fi
|
||||
ARTIFACT="$2"
|
||||
@@ -112,19 +120,37 @@ done
|
||||
# set positional arguments in their proper place
|
||||
eval set -- "$PARAMS"
|
||||
|
||||
# Statically compile the CLI and warpctrl artifacts so they can run on older Linux distros.
|
||||
if [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "warpctrl" ]]; then
|
||||
TARGET_TRIPLE="${BUILD_ARCH}-unknown-linux-musl"
|
||||
# Only configure the musl toolchain when we are actually compiling. Packaging-only
|
||||
# runs (--skip-build) just need TARGET_TRIPLE to locate the prebuilt binary, and
|
||||
# configuring the toolchain there would force an unnecessary (and potentially
|
||||
# failing) musl-cross download on hosts that never compile.
|
||||
if [[ "$BUILD" == "true" ]]; then
|
||||
source "$WORKSPACE_ROOT_DIR/script/linux/configure_musl_toolchain" "$TARGET_TRIPLE"
|
||||
# Make sure we have the rust musl target available.
|
||||
rustup target add "$TARGET_TRIPLE"
|
||||
fi
|
||||
fi
|
||||
CARGO_TARGET_DIR="${CARGO_TARGET_DIR:-$WORKSPACE_ROOT_DIR/target}"
|
||||
CARGO_TARGET_OUTPUT_ROOT="$CARGO_TARGET_DIR${TARGET_TRIPLE:+/$TARGET_TRIPLE}"
|
||||
|
||||
DIST_DIR="$CARGO_TARGET_OUTPUT_ROOT/dist"
|
||||
|
||||
if [[ $DEBUG = true ]]; then
|
||||
CARGO_PROFILE="dev"
|
||||
elif [[ $RELEASE_CHANNEL = "local" || $RELEASE_CHANNEL = "dev" ]]; then
|
||||
# For dev bundles, we want to enable debug assertions to
|
||||
# catch violations that would otherwise silently pass in
|
||||
# a normal release build (e.g. in stable).
|
||||
if [[ "$ARTIFACT" == "cli" ]]; then
|
||||
if [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "warpctrl" ]]; then
|
||||
CARGO_PROFILE="release-cli-debug_assertions"
|
||||
else
|
||||
CARGO_PROFILE="release-lto-debug_assertions"
|
||||
fi
|
||||
else
|
||||
if [[ "$ARTIFACT" == "cli" ]]; then
|
||||
if [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "warpctrl" ]]; then
|
||||
CARGO_PROFILE="release-cli"
|
||||
else
|
||||
CARGO_PROFILE="release-lto"
|
||||
@@ -132,9 +158,9 @@ else
|
||||
fi
|
||||
|
||||
if [[ "$CARGO_PROFILE" == "dev" ]]; then
|
||||
CARGO_TARGET_OUTPUT_DIR="$CARGO_TARGET_DIR/debug"
|
||||
CARGO_TARGET_OUTPUT_DIR="$CARGO_TARGET_OUTPUT_ROOT/debug"
|
||||
else
|
||||
CARGO_TARGET_OUTPUT_DIR="$CARGO_TARGET_DIR/$CARGO_PROFILE"
|
||||
CARGO_TARGET_OUTPUT_DIR="$CARGO_TARGET_OUTPUT_ROOT/$CARGO_PROFILE"
|
||||
fi
|
||||
# NOTE: if you change this path, update the "Clean stale bundle output"
|
||||
# steps in .github/workflows/create_release.yml so they continue to wipe
|
||||
@@ -160,14 +186,16 @@ elif [[ $RELEASE_CHANNEL = "dev" ]]; then
|
||||
BINARY_NAME="warp-dev"
|
||||
APP_NAME="GalaxyDev"
|
||||
FEATURES="$FEATURES,agent_mode_debug"
|
||||
# Enable heap profiling using jemalloc through pprof.
|
||||
FEATURES="$FEATURES,jemalloc_pprof"
|
||||
# Enable heap usage tracking & profiling using jemalloc through pprof.
|
||||
FEATURES="$FEATURES,jemalloc_pprof,heap_usage_tracking"
|
||||
export HANDLE_MARKDOWN=1
|
||||
elif [[ $RELEASE_CHANNEL = "preview" ]]; then
|
||||
WARP_BIN="preview"
|
||||
BINARY_NAME="warp-preview"
|
||||
APP_NAME="GalaxyPreview"
|
||||
FEATURES="$FEATURES,preview_channel"
|
||||
# Enable heap usage tracking & profiling using jemalloc through pprof.
|
||||
FEATURES="$FEATURES,jemalloc_pprof,heap_usage_tracking"
|
||||
elif [[ $RELEASE_CHANNEL = "stable" ]]; then
|
||||
WARP_BIN="stable"
|
||||
BINARY_NAME="warp"
|
||||
@@ -189,13 +217,23 @@ if [[ "$ARTIFACT" == "cli" ]]; then
|
||||
if [[ $RELEASE_CHANNEL != "oss" ]]; then
|
||||
BINARY_NAME="${BINARY_NAME/warp/oz}"
|
||||
fi
|
||||
elif [[ "$ARTIFACT" == "warpctrl" ]]; then
|
||||
BINARY_NAME="warpctrl"
|
||||
PACKAGES=()
|
||||
fi
|
||||
|
||||
# Artifact-specific configuration
|
||||
if [[ "$ARTIFACT" == "cli" ]]; then
|
||||
if [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "warpctrl" ]]; then
|
||||
FEATURES="$FEATURES,standalone"
|
||||
if [[ "$ARTIFACT" == "warpctrl" ]]; then
|
||||
FEATURES="$FEATURES,warp_control_cli"
|
||||
fi
|
||||
elif [[ "$ARTIFACT" == "app" ]]; then
|
||||
FEATURES="$FEATURES,gui,nld_improvements"
|
||||
# All channels ship the v3 classifier and v2 heuristic.
|
||||
FEATURES="$FEATURES,gui,nld_classifier_v3,nld_heuristic_v2"
|
||||
fi
|
||||
if [[ -n "$EXTRA_FEATURES" ]]; then
|
||||
FEATURES="$FEATURES,$EXTRA_FEATURES"
|
||||
fi
|
||||
|
||||
BUNDLE_ID="dev.warp.$APP_NAME"
|
||||
@@ -211,14 +249,15 @@ export APPIMAGE_NAME="$APP_NAME-$BUILD_ARCH.AppImage"
|
||||
# then exit. We use this script to invoke `cargo check` to ensure that we are
|
||||
# using the same feature flags and profile that we would be using in production.
|
||||
if [[ "$CHECK_ONLY" == "true" ]]; then
|
||||
cargo check -p warp --profile "$CARGO_PROFILE" --bin "$WARP_BIN" --features "$FEATURES"
|
||||
cargo check -p warp --profile "$CARGO_PROFILE" --bin "$WARP_BIN" --features "$FEATURES" ${TARGET_TRIPLE:+--target $TARGET_TRIPLE}
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Build the binary.
|
||||
if [[ "$BUILD" == "true" ]]; then
|
||||
echo "Building and bundling Warp for channel $RELEASE_CHANNEL and bundle id $BUNDLE_ID"
|
||||
cargo build -p warp --profile "$CARGO_PROFILE" --bin "$WARP_BIN" --features "$FEATURES"
|
||||
cargo build -p warp --profile "$CARGO_PROFILE" --bin "$WARP_BIN" --features "$FEATURES" ${TARGET_TRIPLE:+--target $TARGET_TRIPLE}
|
||||
|
||||
echo "Making debug copy of '$EXECUTABLE_PATH' at '$DEBUG_EXECUTABLE_PATH'"
|
||||
cp "$EXECUTABLE_PATH" "$DEBUG_EXECUTABLE_PATH"
|
||||
|
||||
@@ -226,18 +265,35 @@ if [[ "$BUILD" == "true" ]]; then
|
||||
if [[ $RELEASE_CHANNEL = "dev" ]]; then
|
||||
# For dev builds, only strip debug symbols, as we want to keep some
|
||||
# symbols for profiling purposes.
|
||||
strip --strip-debug "$EXECUTABLE_PATH"
|
||||
"${WARP_MUSL_STRIP:-strip}" --strip-debug "$EXECUTABLE_PATH"
|
||||
else
|
||||
# For production builds, strip all symbols, to keep the binary size
|
||||
# smaller.
|
||||
strip --strip-all "$EXECUTABLE_PATH"
|
||||
"${WARP_MUSL_STRIP:-strip}" --strip-all "$EXECUTABLE_PATH"
|
||||
fi
|
||||
else
|
||||
echo 'Skipping `cargo build` step due to --skip-build argument'
|
||||
fi
|
||||
|
||||
if [[ "$ARTIFACT" == "warpctrl" ]]; then
|
||||
echo "Copying control-mode binary into $OUT_DIR/$WARP_BIN"
|
||||
cp "$EXECUTABLE_PATH" "$OUT_DIR/$WARP_BIN"
|
||||
WARPCTRL_SCRIPT_PATH="$OUT_DIR/warpctrl"
|
||||
echo "Creating warpctrl wrapper script at $WARPCTRL_SCRIPT_PATH"
|
||||
cat > "$WARPCTRL_SCRIPT_PATH" << EOF
|
||||
#!/usr/bin/env bash
|
||||
script_dir="\$(cd "\$(dirname "\${BASH_SOURCE[0]}")" && pwd)"
|
||||
exec "\$script_dir/$WARP_BIN" --warpctrl "\$@"
|
||||
EOF
|
||||
chmod +x "$WARPCTRL_SCRIPT_PATH"
|
||||
fi
|
||||
BINARY_PATH="$EXECUTABLE_PATH"
|
||||
if [[ "$ARTIFACT" == "warpctrl" ]]; then
|
||||
BINARY_PATH="$WARPCTRL_SCRIPT_PATH"
|
||||
fi
|
||||
|
||||
# Prepare bundled resources for CLI builds.
|
||||
if [[ "$ARTIFACT" == "cli" ]]; then
|
||||
if [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "warpctrl" ]]; then
|
||||
echo "Preparing CLI resources directory"
|
||||
BUNDLED_RESOURCES_DIR="$OUT_DIR/resources"
|
||||
"$WORKSPACE_ROOT_DIR/script/prepare_bundled_resources" "$BUNDLED_RESOURCES_DIR" "$RELEASE_CHANNEL" "$CARGO_PROFILE"
|
||||
@@ -249,7 +305,7 @@ fi
|
||||
# as the directory containing all built packages.
|
||||
if [ "${GITHUB_ACTIONS}" == "true" ]; then
|
||||
echo "::echo::on"
|
||||
echo "executable_path=$EXECUTABLE_PATH" >> "$GITHUB_OUTPUT"
|
||||
echo "executable_path=$BINARY_PATH" >> "$GITHUB_OUTPUT"
|
||||
echo "debug_executable_path=$DEBUG_EXECUTABLE_PATH" >> "$GITHUB_OUTPUT"
|
||||
echo "packages_dir=$OUT_DIR" >> "$GITHUB_OUTPUT"
|
||||
echo "bundled_resources_dir=${BUNDLED_RESOURCES_DIR:-}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
Executable
+236
@@ -0,0 +1,236 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# This script configures a complete musl C and C++ toolchain for a Rust target.
|
||||
# Source this script so it can update the caller's environment.
|
||||
|
||||
configure_musl_toolchain() {
|
||||
local target="${1:-$(uname -m)-unknown-linux-musl}"
|
||||
local musl_cross_tag="20250929"
|
||||
local musl_cross_sha256
|
||||
|
||||
case "$target" in
|
||||
aarch64-unknown-linux-musl)
|
||||
musl_cross_sha256="28a1d26f14f8ddc3aed31f20705fe696777400eb5952d90470a7e6e2dd1175bb"
|
||||
;;
|
||||
x86_64-unknown-linux-musl)
|
||||
musl_cross_sha256="6534870abd7dc327fd2e14cc53972d0552b21f47db5769505534f788537e3544"
|
||||
;;
|
||||
*)
|
||||
echo "Error: unsupported musl target '$target'." >&2
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
local compiler_prefix
|
||||
local musl_cc=""
|
||||
local musl_cxx=""
|
||||
local musl_strip=""
|
||||
for compiler_prefix in "$target" "${target/unknown-/}"; do
|
||||
if command -v "$compiler_prefix-gcc" &>/dev/null \
|
||||
&& command -v "$compiler_prefix-g++" &>/dev/null \
|
||||
&& command -v "$compiler_prefix-strip" &>/dev/null; then
|
||||
musl_cc="$(command -v "$compiler_prefix-gcc")"
|
||||
musl_cxx="$(command -v "$compiler_prefix-g++")"
|
||||
musl_strip="$(command -v "$compiler_prefix-strip")"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ -z "$musl_cc" && "$target" == "$(uname -m)-unknown-linux-musl" ]] \
|
||||
&& command -v musl-gcc &>/dev/null \
|
||||
&& command -v musl-g++ &>/dev/null \
|
||||
&& command -v strip &>/dev/null; then
|
||||
musl_cc="$(command -v musl-gcc)"
|
||||
musl_cxx="$(command -v musl-g++)"
|
||||
musl_strip="$(command -v strip)"
|
||||
fi
|
||||
|
||||
local default_musl_cross_root
|
||||
if [[ -z "${WARP_MUSL_CROSS_ROOT:-}" && "${GITHUB_ACTIONS:-}" == "true" && -n "${RUNNER_TEMP:-}" ]]; then
|
||||
default_musl_cross_root="$RUNNER_TEMP/warp-musl-cross"
|
||||
elif [[ -n "${HOME:-}" ]]; then
|
||||
default_musl_cross_root="${XDG_CACHE_HOME:-$HOME/.cache}/warp-musl-cross"
|
||||
else
|
||||
default_musl_cross_root="${TMPDIR:-/tmp}/warp-musl-cross-${UID:-$(id -u)}"
|
||||
fi
|
||||
|
||||
local musl_cross_root="${WARP_MUSL_CROSS_ROOT:-$default_musl_cross_root}"
|
||||
local install_root="$musl_cross_root/$musl_cross_tag"
|
||||
local toolchain_dir="$install_root/$target"
|
||||
local toolchain_bin="$toolchain_dir/bin"
|
||||
local verified_marker="$toolchain_dir/.warp-musl-cross-verified"
|
||||
local verified_marker_contents="$musl_cross_tag $target $musl_cross_sha256"
|
||||
|
||||
ensure_private_cache_dir() {
|
||||
local dir="$1"
|
||||
|
||||
if [[ -L "$dir" ]]; then
|
||||
echo "Error: musl toolchain cache directory '$dir' must not be a symlink." >&2
|
||||
return 1
|
||||
fi
|
||||
if [[ -e "$dir" && ! -d "$dir" ]]; then
|
||||
echo "Error: musl toolchain cache path '$dir' exists but is not a directory." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
mkdir -p "$dir" || return 1
|
||||
chmod 700 "$dir" || return 1
|
||||
if [[ ! -O "$dir" ]]; then
|
||||
echo "Error: musl toolchain cache directory '$dir' must be owned by the current user." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
local mode
|
||||
if mode="$(stat -c '%a' "$dir" 2>/dev/null)"; then
|
||||
:
|
||||
elif mode="$(stat -f '%Lp' "$dir" 2>/dev/null)"; then
|
||||
:
|
||||
else
|
||||
echo "Error: could not determine permissions for musl toolchain cache directory '$dir'." >&2
|
||||
return 1
|
||||
fi
|
||||
if (( (8#$mode & 0022) != 0 )); then
|
||||
echo "Error: musl toolchain cache directory '$dir' must not be writable by group or others." >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
cached_toolchain_is_verified() {
|
||||
[[ -r "$verified_marker" ]] && [[ "$(cat "$verified_marker")" == "$verified_marker_contents" ]]
|
||||
}
|
||||
|
||||
if [[ -z "$musl_cc" ]]; then
|
||||
ensure_private_cache_dir "$musl_cross_root" || return 1
|
||||
ensure_private_cache_dir "$install_root" || return 1
|
||||
fi
|
||||
|
||||
if [[ -z "$musl_cc" && -L "$toolchain_dir" ]]; then
|
||||
echo "Error: cached musl toolchain path '$toolchain_dir' must not be a symlink." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ -z "$musl_cc" ]]; then
|
||||
if [[ -d "$toolchain_dir" ]] && ! cached_toolchain_is_verified; then
|
||||
echo "Ignoring unverified cached musl toolchain at '$toolchain_dir'." >&2
|
||||
fi
|
||||
|
||||
if cached_toolchain_is_verified \
|
||||
&& [[ -x "$toolchain_bin/$target-gcc" ]] \
|
||||
&& [[ -x "$toolchain_bin/$target-g++" ]] \
|
||||
&& [[ -x "$toolchain_bin/$target-strip" ]]; then
|
||||
case ":$PATH:" in
|
||||
*":$toolchain_bin:"*) ;;
|
||||
*) export PATH="$toolchain_bin:$PATH" ;;
|
||||
esac
|
||||
musl_cc="$(command -v "$target-gcc")"
|
||||
musl_cxx="$(command -v "$target-g++")"
|
||||
musl_strip="$(command -v "$target-strip")"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z "$musl_cc" ]]; then
|
||||
if [[ "$(uname -s)" != "Linux" ]]; then
|
||||
echo "Error: no complete C and C++ toolchain for '$target' was found on PATH." >&2
|
||||
echo "Automatic musl-cross installation is only supported on Linux." >&2
|
||||
return 1
|
||||
fi
|
||||
if [[ "$(uname -m)" != "x86_64" ]]; then
|
||||
echo "Error: automatic musl-cross installation is only supported on x86_64 hosts." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
local required_command
|
||||
for required_command in curl sha256sum tar; do
|
||||
if ! command -v "$required_command" &>/dev/null; then
|
||||
echo "Error: '$required_command' is required to install the musl toolchain." >&2
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
|
||||
local archive_name="$target.tar.xz"
|
||||
local archive_url="https://github.com/cross-tools/musl-cross/releases/download/$musl_cross_tag/$archive_name"
|
||||
if ! (
|
||||
download_dir=""
|
||||
cleanup_download() {
|
||||
if [[ -n "$download_dir" && -d "$download_dir" ]]; then
|
||||
chmod -R u+w "$download_dir" 2>/dev/null || true
|
||||
rm -rf "$download_dir"
|
||||
fi
|
||||
}
|
||||
trap cleanup_download EXIT
|
||||
|
||||
ensure_private_cache_dir "$musl_cross_root" || exit 1
|
||||
ensure_private_cache_dir "$install_root" || exit 1
|
||||
download_dir="$(mktemp -d "$musl_cross_root/.download-$target.XXXXXX")" || exit 1
|
||||
|
||||
echo "Downloading the $target C and C++ toolchain to $toolchain_dir"
|
||||
curl -fsSL --retry 3 "$archive_url" -o "$download_dir/$archive_name" || exit 1
|
||||
printf '%s %s\n' "$musl_cross_sha256" "$download_dir/$archive_name" | sha256sum -c - || exit 1
|
||||
tar -xf "$download_dir/$archive_name" -C "$download_dir" || exit 1
|
||||
if [[ ! -x "$download_dir/$target/bin/$target-gcc" \
|
||||
|| ! -x "$download_dir/$target/bin/$target-g++" \
|
||||
|| ! -x "$download_dir/$target/bin/$target-strip" ]]; then
|
||||
echo "Error: the downloaded archive does not contain the expected C, C++, and strip tools." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
chmod -R u+w,go-w "$download_dir/$target" || exit 1
|
||||
printf '%s\n' "$verified_marker_contents" > "$download_dir/$target/.warp-musl-cross-verified" || exit 1
|
||||
if [[ -x "$toolchain_bin/$target-gcc" \
|
||||
&& -x "$toolchain_bin/$target-g++" \
|
||||
&& -x "$toolchain_bin/$target-strip" \
|
||||
&& -r "$verified_marker" \
|
||||
&& "$(cat "$verified_marker")" == "$verified_marker_contents" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
if [[ -e "$toolchain_dir" ]]; then
|
||||
chmod -R u+w "$toolchain_dir" || exit 1
|
||||
rm -rf "$toolchain_dir" || exit 1
|
||||
fi
|
||||
mv "$download_dir/$target" "$toolchain_dir" || exit 1
|
||||
); then
|
||||
return 1
|
||||
fi
|
||||
|
||||
case ":$PATH:" in
|
||||
*":$toolchain_bin:"*) ;;
|
||||
*) export PATH="$toolchain_bin:$PATH" ;;
|
||||
esac
|
||||
musl_cc="$(command -v "$target-gcc")"
|
||||
musl_cxx="$(command -v "$target-g++")"
|
||||
musl_strip="$(command -v "$target-strip")"
|
||||
fi
|
||||
|
||||
local tool
|
||||
for tool in "$musl_cc" "$musl_cxx" "$musl_strip"; do
|
||||
if ! "$tool" --version &>/dev/null; then
|
||||
echo "Error: musl tool '$tool' cannot execute on this host." >&2
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
|
||||
local target_env="${target//-/_}"
|
||||
local cargo_target_env
|
||||
cargo_target_env="$(printf '%s' "$target" | tr '[:lower:]-' '[:upper:]_')"
|
||||
|
||||
export "CC_$target_env=$musl_cc"
|
||||
export "CXX_$target_env=$musl_cxx"
|
||||
export "CARGO_TARGET_${cargo_target_env}_LINKER=$musl_cc"
|
||||
export WARP_MUSL_TARGET="$target"
|
||||
export WARP_MUSL_CC="$musl_cc"
|
||||
export WARP_MUSL_CXX="$musl_cxx"
|
||||
export WARP_MUSL_STRIP="$musl_strip"
|
||||
|
||||
echo "Configured the $target toolchain with $musl_cc, $musl_cxx, and $musl_strip"
|
||||
}
|
||||
|
||||
if [[ -n "${BASH_VERSION:-}" && "${BASH_SOURCE[0]}" == "$0" ]]; then
|
||||
echo "Error: source this script so it can configure the caller's environment." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ -n "${ZSH_VERSION:-}" && "${ZSH_EVAL_CONTEXT:-}" != *:file ]]; then
|
||||
echo "Error: source this script so it can configure the caller's environment." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
configure_musl_toolchain "$@"
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
set -e
|
||||
|
||||
. "$PWD/script/warp_sudo"
|
||||
|
||||
# Define some control sequences for text formatting.
|
||||
red="\033[0;31m"
|
||||
reset="\033[0m"
|
||||
@@ -33,8 +35,16 @@ if [[ "$(source /etc/os-release; echo $ID $ID_LIKE)" = *"debian"* ]]; then
|
||||
brotli
|
||||
# Needed for voice input
|
||||
libasound2-dev
|
||||
# Needed by bindgen (used by minimp4-sys, pulled in by warpui_core's
|
||||
# integration_tests feature) — pulls in libclang-common-*-dev which
|
||||
# provides clang's resource-dir builtin headers.
|
||||
libclang-dev
|
||||
# Required by script/presubmit's clang-format check on C/C++/Obj-C sources.
|
||||
clang-format
|
||||
# Required to build statically-linked binaries for Linux.
|
||||
musl-tools
|
||||
)
|
||||
sudo apt-get install -y "${PACKAGES[@]}"
|
||||
warp_sudo apt-get install -y "${PACKAGES[@]}"
|
||||
|
||||
# Install a modern version of protoc. The apt 'protobuf-compiler' package on
|
||||
# Ubuntu 20.04 ships protoc 3.6.1, which is too old for proto3 'optional'
|
||||
@@ -47,7 +57,7 @@ if [[ "$(source /etc/os-release; echo $ID $ID_LIKE)" = *"debian"* ]]; then
|
||||
esac
|
||||
curl -fsSL -o /tmp/protoc.zip \
|
||||
"https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/${PROTOC_ZIP}"
|
||||
sudo unzip -o /tmp/protoc.zip -d /usr/local bin/protoc 'include/*'
|
||||
warp_sudo unzip -o /tmp/protoc.zip -d /usr/local bin/protoc 'include/*'
|
||||
rm /tmp/protoc.zip
|
||||
else
|
||||
echo -e "⚠️ ${red}Unknown Linux distribution; necessary build dependencies may not be installed!${reset}"
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
set -e
|
||||
|
||||
. "$PWD/script/warp_sudo"
|
||||
|
||||
# Define some control sequences for text formatting.
|
||||
red="\033[0;31m"
|
||||
reset="\033[0m"
|
||||
@@ -34,7 +36,7 @@ if [[ "$(source /etc/os-release; echo $ID $ID_LIKE)" = *"debian"* ]]; then
|
||||
# Ensuring at least one cursor library for WSL.
|
||||
yaru-theme-icon
|
||||
)
|
||||
sudo apt-get install -y "${PACKAGES[@]}"
|
||||
warp_sudo apt-get install -y "${PACKAGES[@]}"
|
||||
else
|
||||
echo -e "⚠️ ${red}Unknown Linux distribution; necessary runtime dependencies may not be installed!${reset}"
|
||||
fi
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
set -e
|
||||
|
||||
. "$PWD/script/warp_sudo"
|
||||
|
||||
# Define some control sequences for text formatting.
|
||||
red="\033[0;31m"
|
||||
reset="\033[0m"
|
||||
@@ -23,15 +25,15 @@ if [[ "$(source /etc/os-release; echo $ID $ID_LIKE)" = *"debian"* ]]; then
|
||||
# We run vim in some integration tests to test the altscreen.
|
||||
vim
|
||||
)
|
||||
sudo apt-get install -y "${PACKAGES[@]}"
|
||||
warp_sudo apt-get install -y "${PACKAGES[@]}"
|
||||
|
||||
# If gcloud is not already installed, install it so that we can run SSH integration tests.
|
||||
if [[ ! -x "$(command -v gcloud)" ]]; then
|
||||
echo "⬇️ Installing the gcloud CLI..."
|
||||
echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] http://packages.cloud.google.com/apt cloud-sdk main" | sudo tee /etc/apt/sources.list.d/google-cloud-sdk.list
|
||||
curl -f https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key --keyring /usr/share/keyrings/cloud.google.gpg add -
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install google-cloud-cli -y
|
||||
echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] http://packages.cloud.google.com/apt cloud-sdk main" | warp_sudo tee /etc/apt/sources.list.d/google-cloud-sdk.list
|
||||
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | warp_sudo gpg --dearmor --yes -o /usr/share/keyrings/cloud.google.gpg
|
||||
warp_sudo apt-get update -y
|
||||
warp_sudo apt-get install google-cloud-cli -y
|
||||
fi
|
||||
else
|
||||
echo -e "⚠️ ${red}Unknown Linux distribution; necessary test dependencies may not be installed!${reset}"
|
||||
|
||||
Executable
+80
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
workspace_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
temp_dir="$(mktemp -d)"
|
||||
trap 'rm -rf "$temp_dir"' EXIT
|
||||
|
||||
mkdir -p "$temp_dir/bin"
|
||||
cat > "$temp_dir/bin/cargo" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
printf '%s\n' "$@" > "$CARGO_ARGS_FILE"
|
||||
EOF
|
||||
chmod +x "$temp_dir/bin/cargo"
|
||||
cat > "$temp_dir/bin/rustup" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
exit 0
|
||||
EOF
|
||||
chmod +x "$temp_dir/bin/rustup"
|
||||
|
||||
case "$(uname -m)" in
|
||||
arm64|aarch64)
|
||||
arch="aarch64"
|
||||
;;
|
||||
x86_64|amd64)
|
||||
arch="x86_64"
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported architecture: $(uname -m)" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
target="$arch-unknown-linux-musl"
|
||||
for compiler in "$target-gcc" "$target-g++" "$target-strip"; do
|
||||
cat > "$temp_dir/bin/$compiler" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
exit 0
|
||||
EOF
|
||||
chmod +x "$temp_dir/bin/$compiler"
|
||||
done
|
||||
|
||||
PATH="$temp_dir/bin:$PATH" \
|
||||
CARGO_ARGS_FILE="$temp_dir/cargo-args" \
|
||||
CARGO_TARGET_DIR="$temp_dir/target" \
|
||||
"$workspace_root/script/linux/bundle" \
|
||||
--check-only \
|
||||
--artifact warpctrl \
|
||||
--arch "$arch" \
|
||||
--features smoke_feature
|
||||
|
||||
grep -qx -- '--features' "$temp_dir/cargo-args"
|
||||
grep -qx -- 'release_bundle,crash_reporting,agent_mode_debug,jemalloc_pprof,heap_usage_tracking,standalone,warp_control_cli,smoke_feature' "$temp_dir/cargo-args"
|
||||
|
||||
profile_dir="$temp_dir/target/$target/release-cli-debug_assertions"
|
||||
mkdir -p "$profile_dir"
|
||||
cat > "$profile_dir/dev" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
printf '%s\n' "$@" > "$FORWARDED_ARGS_FILE"
|
||||
EOF
|
||||
chmod +x "$profile_dir/dev"
|
||||
|
||||
PATH="$temp_dir/bin:$PATH" \
|
||||
CARGO_TARGET_DIR="$temp_dir/target" \
|
||||
NO_LICENSES=1 \
|
||||
SKIP_SETTINGS_SCHEMA=1 \
|
||||
"$workspace_root/script/linux/bundle" \
|
||||
--skip-build \
|
||||
--artifact warpctrl \
|
||||
--arch "$arch"
|
||||
|
||||
FORWARDED_ARGS_FILE="$temp_dir/forwarded-args" \
|
||||
"$profile_dir/bundle/linux/warpctrl" tab create --instance "inst 123"
|
||||
|
||||
cat > "$temp_dir/expected-forwarded-args" <<'EOF'
|
||||
--warpctrl
|
||||
tab
|
||||
create
|
||||
--instance
|
||||
inst 123
|
||||
EOF
|
||||
cmp "$temp_dir/expected-forwarded-args" "$temp_dir/forwarded-args"
|
||||
+24
-5
@@ -5,12 +5,31 @@
|
||||
|
||||
set -e
|
||||
|
||||
if ! [ -d "/Applications/Xcode.app" ]; then
|
||||
echo "Please install Xcode from the App Store before continuing."
|
||||
exit 1
|
||||
fi
|
||||
. "$PWD/script/warp_sudo"
|
||||
|
||||
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
|
||||
DEVELOPER_DIR="$(xcode-select -p 2>/dev/null || true)"
|
||||
if [ -z "$DEVELOPER_DIR" ] || [ ! -x "$DEVELOPER_DIR/usr/bin/xcodebuild" ] || [ "$DEVELOPER_DIR" = "/Library/Developer/CommandLineTools" ]; then
|
||||
XCODE_APP=""
|
||||
# Prefer the stable /Applications/Xcode.app when present so users with
|
||||
# both stable and beta/versioned installs aren't switched away from it.
|
||||
if [ -x "/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild" ]; then
|
||||
XCODE_APP="/Applications/Xcode.app"
|
||||
else
|
||||
for candidate in /Applications/Xcode*.app; do
|
||||
if [ -x "$candidate/Contents/Developer/usr/bin/xcodebuild" ]; then
|
||||
XCODE_APP="$candidate"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [ -z "$XCODE_APP" ]; then
|
||||
echo "Please install Xcode before continuing."
|
||||
exit 1
|
||||
fi
|
||||
echo "Selected Xcode at $XCODE_APP"
|
||||
echo "You may be prompted for your password so bootstrap can set Xcode as the active developer directory."
|
||||
warp_sudo xcode-select --switch "$XCODE_APP/Contents/Developer"
|
||||
fi
|
||||
# Mimic actually launching XCode, which performs some necessary set-up of the
|
||||
# development environment.
|
||||
xcodebuild -runFirstLaunch
|
||||
|
||||
+49
-12
@@ -223,8 +223,8 @@ while (( "$#" )); do
|
||||
;;
|
||||
--artifact)
|
||||
if [ -n "$2" ] && [ "${2:0:1}" != "-" ]; then
|
||||
if [[ "$2" != "app" && "$2" != "cli" ]]; then
|
||||
echo "Error: --artifact must be either 'app' or 'cli', got '$2'" >&2
|
||||
if [[ "$2" != "app" && "$2" != "cli" && "$2" != "warpctrl" ]]; then
|
||||
echo "Error: --artifact must be 'app', 'cli', or 'warpctrl', got '$2'" >&2
|
||||
exit 1
|
||||
fi
|
||||
ARTIFACT="$2"
|
||||
@@ -250,13 +250,13 @@ elif [[ $RELEASE_CHANNEL = "local" || $RELEASE_CHANNEL = "dev" ]]; then
|
||||
# For dev bundles, we want to enable debug assertions to
|
||||
# catch violations that would otherwise silently pass in
|
||||
# a normal release build (e.g. in stable).
|
||||
if [[ "$ARTIFACT" == "cli" ]]; then
|
||||
if [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "warpctrl" ]]; then
|
||||
CARGO_PROFILE="release-cli-debug_assertions"
|
||||
else
|
||||
CARGO_PROFILE="release-lto-debug_assertions"
|
||||
fi
|
||||
else
|
||||
if [[ "$ARTIFACT" == "cli" ]]; then
|
||||
if [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "warpctrl" ]]; then
|
||||
CARGO_PROFILE="release-cli"
|
||||
else
|
||||
CARGO_PROFILE="release-lto"
|
||||
@@ -286,6 +286,8 @@ elif [[ $RELEASE_CHANNEL = "dev" ]]; then
|
||||
FEATURES="$FEATURES,agent_mode_debug"
|
||||
# Enable heap usage tracking & profiling using jemalloc through pprof.
|
||||
FEATURES="$FEATURES,jemalloc_pprof,heap_usage_tracking"
|
||||
# Enable the Warp Control CLI wrapper for local scripting/automation.
|
||||
FEATURES="$FEATURES,warp_control_cli"
|
||||
# For dev builds, use different versions of our bundled frameworks (e.g.:
|
||||
# Sentry). This needs to be exported so it can be referenced by
|
||||
# app/build.rs later, while running `cargo bundle`.
|
||||
@@ -304,6 +306,8 @@ elif [[ $RELEASE_CHANNEL = "stable" ]]; then
|
||||
BUNDLE_ID="com.samsung.Galaxy"
|
||||
WARP_APP_NAME="Galaxy"
|
||||
WARP_SCHEME_NAME="galaxy"
|
||||
# Enable heap usage tracking & profiling using jemalloc through pprof.
|
||||
FEATURES="$FEATURES,jemalloc_pprof,heap_usage_tracking"
|
||||
elif [[ $RELEASE_CHANNEL = "oss" ]]; then
|
||||
WARP_BIN="galaxy-ai-oss"
|
||||
BUNDLE_ID="com.samsung.Galaxy"
|
||||
@@ -345,12 +349,13 @@ else
|
||||
fi
|
||||
|
||||
# Set artifact-specific configuration.
|
||||
if [[ "$ARTIFACT" == cli ]]; then
|
||||
if [[ "$ARTIFACT" == cli || "$ARTIFACT" == warpctrl ]]; then
|
||||
UNIVERSAL_BINARY=false
|
||||
OPEN_AFTER_BUNDLE=false
|
||||
FEATURES="$FEATURES,standalone"
|
||||
elif [[ "$ARTIFACT" == app ]]; then
|
||||
FEATURES="$FEATURES,gui,nld_improvements"
|
||||
# All channels ship the v3 classifier and v2 heuristic.
|
||||
FEATURES="$FEATURES,gui,nld_classifier_v3,nld_heuristic_v2"
|
||||
fi
|
||||
|
||||
# If we're building a universal bundle for the app artifact, make sure the additional target is available.
|
||||
@@ -363,7 +368,7 @@ fi
|
||||
# using the same feature flags and profile that we would be using in production.
|
||||
if [[ "$CHECK_ONLY" == "true" ]]; then
|
||||
cargo check --profile "$CARGO_PROFILE" --bin "$WARP_BIN" --target "$DEFAULT_TARGET" --features "$FEATURES"
|
||||
if [[ $UNIVERSAL_BINARY = true && "$ARTIFACT" != "cli" ]]; then
|
||||
if [[ $UNIVERSAL_BINARY = true && "$ARTIFACT" != "cli" && "$ARTIFACT" != "warpctrl" ]]; then
|
||||
cargo check --profile "$CARGO_PROFILE" --bin "$WARP_BIN" --target "$ADDITIONAL_TARGET" --features "$FEATURES"
|
||||
fi
|
||||
exit 0
|
||||
@@ -551,10 +556,26 @@ EOF
|
||||
# Make the script executable
|
||||
chmod +x "$CLI_SCRIPT_PATH"
|
||||
|
||||
if [[ ",$FEATURES," =~ ",warp_control_cli," ]]; then
|
||||
# Each value must match `Channel::warpctrl_command_name` in the Rust source.
|
||||
if [[ $RELEASE_CHANNEL = "stable" ]]; then
|
||||
WARPCTRL_COMMAND_NAME="warpctrl"
|
||||
elif [[ $RELEASE_CHANNEL = "oss" ]]; then
|
||||
WARPCTRL_COMMAND_NAME="warpctrl-oss"
|
||||
else
|
||||
WARPCTRL_COMMAND_NAME="warpctrl-$RELEASE_CHANNEL"
|
||||
fi
|
||||
WARPCTRL_SCRIPT_PATH="$BUNDLED_RESOURCES_DIR/bin/$WARPCTRL_COMMAND_NAME"
|
||||
echo "Creating warpctrl wrapper script at $WARPCTRL_SCRIPT_PATH..."
|
||||
"$WORKSPACE_ROOT_DIR/script/macos/create_warpctrl_wrapper" \
|
||||
"$WARPCTRL_SCRIPT_PATH" \
|
||||
"../../MacOS/$WARP_BIN"
|
||||
fi
|
||||
|
||||
# Store the built artifact locations for GitHub Actions outputs.
|
||||
BINARY_PATH="target/$DEFAULT_TARGET/$TARGET_PROFILE_DIR/$WARP_BIN"
|
||||
DMG_PATH="$OUT_DIR/$FINAL_DMG_NAME"
|
||||
elif [[ "$ARTIFACT" == "cli" ]]; then
|
||||
elif [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "warpctrl" ]]; then
|
||||
if [[ $BUILD_BINARY == true ]]; then
|
||||
# Create Info.plist before building the app, since it's embedded at build time.
|
||||
# Apple's codesigning tools will detect Info.plist files in the same directory as an executable.
|
||||
@@ -581,6 +602,18 @@ elif [[ "$ARTIFACT" == "cli" ]]; then
|
||||
echo "Copying binary into $OUT_DIR/$WARP_BIN"
|
||||
cp "target/$DEFAULT_TARGET/$TARGET_PROFILE_DIR/$WARP_BIN" "$OUT_DIR/$WARP_BIN"
|
||||
|
||||
if [[ "$ARTIFACT" == "warpctrl" ]]; then
|
||||
if [[ ! ",$FEATURES," =~ ",warp_control_cli," ]]; then
|
||||
echo "warpctrl artifact requires the warp_control_cli feature" >&2
|
||||
exit 1
|
||||
fi
|
||||
WARPCTRL_SCRIPT_PATH="$OUT_DIR/warpctrl"
|
||||
echo "Creating warpctrl wrapper script at $WARPCTRL_SCRIPT_PATH"
|
||||
"$WORKSPACE_ROOT_DIR/script/macos/create_warpctrl_wrapper" \
|
||||
"$WARPCTRL_SCRIPT_PATH" \
|
||||
"$WARP_BIN"
|
||||
fi
|
||||
|
||||
if [[ -n "$TARGET_ARCH" && -e "target/$DEFAULT_TARGET/$TARGET_PROFILE_DIR/$WARP_BIN.dSYM" ]]; then
|
||||
echo "Copying .dSYM into $OUT_DIR/$WARP_BIN.dSYM"
|
||||
cp -HR "target/$DEFAULT_TARGET/$TARGET_PROFILE_DIR/$WARP_BIN.dSYM" "$OUT_DIR/"
|
||||
@@ -592,7 +625,11 @@ elif [[ "$ARTIFACT" == "cli" ]]; then
|
||||
|
||||
|
||||
# Set the primary binary path to output.
|
||||
BINARY_PATH="$OUT_DIR/$WARP_BIN"
|
||||
if [[ "$ARTIFACT" == "warpctrl" ]]; then
|
||||
BINARY_PATH="$OUT_DIR/warpctrl"
|
||||
else
|
||||
BINARY_PATH="$OUT_DIR/$WARP_BIN"
|
||||
fi
|
||||
else
|
||||
echo "Unsupported artifact: $ARTIFACT" >&2
|
||||
exit 1
|
||||
@@ -659,7 +696,7 @@ if [[ $SELFSIGN = true ]]; then
|
||||
if [[ "$ARTIFACT" == app ]]; then
|
||||
echo "Self-signing $BUNDLE_DIR/$WARP_APP_NAME.app with ${SIGNING_CERT}..."
|
||||
codesign --force --deep --options runtime --sign "$SIGNING_CERT" "$BUNDLE_DIR/$WARP_APP_NAME.app" --entitlements script/Debug-Entitlements.plist
|
||||
elif [[ "$ARTIFACT" == cli ]]; then
|
||||
elif [[ "$ARTIFACT" == cli || "$ARTIFACT" == warpctrl ]]; then
|
||||
echo "Self-signing $OUT_DIR/$WARP_BIN with ${SIGNING_CERT}..."
|
||||
codesign --force --options runtime --sign "$SIGNING_CERT" "$OUT_DIR/$WARP_BIN" --entitlements script/Debug-Entitlements.plist
|
||||
fi
|
||||
@@ -668,7 +705,7 @@ elif [[ $CODESIGN = true ]]; then
|
||||
echo "Codesigning $BUNDLE_DIR/$WARP_APP_NAME.app..."
|
||||
# Use --deep so we sign bundled frameworks as well
|
||||
codesign --deep -f -o runtime --timestamp -s "$APPLE_TEAM_ID" "$BUNDLE_DIR/$WARP_APP_NAME.app" --entitlements script/Entitlements.plist
|
||||
elif [[ "$ARTIFACT" == cli ]]; then
|
||||
elif [[ "$ARTIFACT" == cli || "$ARTIFACT" == warpctrl ]]; then
|
||||
echo "Codesigning $OUT_DIR/$WARP_BIN..."
|
||||
codesign -f -o runtime --timestamp -s "$APPLE_TEAM_ID" "$OUT_DIR/$WARP_BIN" --entitlements script/Entitlements.plist
|
||||
|
||||
@@ -779,7 +816,7 @@ if [[ $CODESIGN = true ]]; then
|
||||
echo "Verifying notarization ticket..."
|
||||
if [[ "$ARTIFACT" = app ]]; then
|
||||
xcrun stapler validate "$DMG_DIR/$DMG_NAME"
|
||||
elif [[ "$ARTIFACT" = cli ]]; then
|
||||
elif [[ "$ARTIFACT" = cli || "$ARTIFACT" = warpctrl ]]; then
|
||||
spctl -a -t open --context context:primary-signature -vv "$OUT_DIR/$WARP_BIN"
|
||||
fi
|
||||
fi
|
||||
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
if [[ $# -ne 2 ]]; then
|
||||
echo "Usage: $0 <wrapper-path> <binary-relative-path>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
WRAPPER_PATH="$1"
|
||||
BINARY_RELATIVE_PATH="$2"
|
||||
|
||||
mkdir -p "$(dirname "$WRAPPER_PATH")"
|
||||
cat > "$WRAPPER_PATH" << EOF
|
||||
#!/bin/bash
|
||||
# This wrapper may be installed through a symlink in /usr/local/bin. Resolve
|
||||
# symlinks before locating the Warp executable relative to the bundled wrapper.
|
||||
wrapper_path="\${BASH_SOURCE[0]}"
|
||||
while [[ -L "\$wrapper_path" ]]; do
|
||||
wrapper_dir="\$(cd -P "\$(dirname "\$wrapper_path")" && pwd)"
|
||||
wrapper_path="\$(readlink "\$wrapper_path")"
|
||||
if [[ "\$wrapper_path" != /* ]]; then
|
||||
wrapper_path="\$wrapper_dir/\$wrapper_path"
|
||||
fi
|
||||
done
|
||||
script_dir="\$(cd -P "\$(dirname "\$wrapper_path")" && pwd)"
|
||||
|
||||
# Warp Control has a separate argument parser from the normal Warp/Oz parser.
|
||||
# The hidden flag selects it before normal CLI parsing or GUI startup.
|
||||
# Replace the wrapper process while preserving its invocation name as argv[0].
|
||||
exec -a "\$0" "\$script_dir/$BINARY_RELATIVE_PATH" --warpctrl "\$@"
|
||||
EOF
|
||||
chmod +x "$WRAPPER_PATH"
|
||||
+36
-11
@@ -21,11 +21,19 @@ cd "${REPO_ROOT}"
|
||||
: "${WARP_CHANNEL:?WARP_CHANNEL must be set (invoke via ./script/run)}"
|
||||
: "${FEATURES:?FEATURES must be set (invoke via ./script/run)}"
|
||||
|
||||
# Resolve Cargo's actual target directory rather than assuming ./target. This
|
||||
# honors a shared CARGO_TARGET_DIR / build.target-dir (e.g. set in
|
||||
# ~/.cargo/config.toml), which is where `cargo bundle` writes the .app bundle.
|
||||
TARGET_DIR="$(cargo metadata --no-deps --format-version 1 | jq -r .target_directory)"
|
||||
if [ -z "$TARGET_DIR" ] || [ "$TARGET_DIR" = "null" ]; then
|
||||
TARGET_DIR="${REPO_ROOT}/target"
|
||||
fi
|
||||
|
||||
if [ "$WARP_CHANNEL" = "local" ]; then
|
||||
WARP_APP_PATH="target/debug/bundle/osx/Galaxy Local.app"
|
||||
WARP_APP_PATH="${TARGET_DIR}/debug/bundle/osx/Galaxy Local.app"
|
||||
WARP_SCHEME_NAME="galaxylocal"
|
||||
else
|
||||
WARP_APP_PATH="target/debug/bundle/osx/Galaxy.app"
|
||||
WARP_APP_PATH="${TARGET_DIR}/debug/bundle/osx/Galaxy.app"
|
||||
WARP_SCHEME_NAME="galaxyoss"
|
||||
fi
|
||||
DONT_OPEN=false
|
||||
@@ -58,11 +66,11 @@ while (( "$#" )); do
|
||||
shift
|
||||
;;
|
||||
--release)
|
||||
echo "Detected release build, pointing at release bundle under target/release/bundle"
|
||||
echo "Detected release build, pointing at release bundle under ${TARGET_DIR}/release/bundle"
|
||||
if [ "$WARP_CHANNEL" = "local" ]; then
|
||||
WARP_APP_PATH="target/release/bundle/osx/Galaxy Local.app"
|
||||
WARP_APP_PATH="${TARGET_DIR}/release/bundle/osx/Galaxy Local.app"
|
||||
else
|
||||
WARP_APP_PATH="target/release/bundle/osx/Galaxy.app"
|
||||
WARP_APP_PATH="${TARGET_DIR}/release/bundle/osx/Galaxy.app"
|
||||
fi
|
||||
PARAMS="$PARAMS $1"
|
||||
shift
|
||||
@@ -71,9 +79,9 @@ while (( "$#" )); do
|
||||
PROFILE="$2"
|
||||
shift 2
|
||||
if [ "$WARP_CHANNEL" = "local" ]; then
|
||||
WARP_APP_PATH="target/${PROFILE}/bundle/osx/Galaxy Local.app"
|
||||
WARP_APP_PATH="${TARGET_DIR}/${PROFILE}/bundle/osx/Galaxy Local.app"
|
||||
else
|
||||
WARP_APP_PATH="target/${PROFILE}/bundle/osx/Galaxy.app"
|
||||
WARP_APP_PATH="${TARGET_DIR}/${PROFILE}/bundle/osx/Galaxy.app"
|
||||
fi
|
||||
PARAMS="$PARAMS --profile $PROFILE"
|
||||
;;
|
||||
@@ -103,6 +111,7 @@ popd > /dev/null
|
||||
if [[ ",$FEATURES," =~ ",cocoa_sentry," ]]; then
|
||||
echo "Copying Sentry framework into app bundle..."
|
||||
SENTRY_FRAMEWORK="app/frameworks/dev/Sentry-Dynamic-WithARM64e.xcframework/macos-arm64_arm64e_x86_64/Sentry.framework"
|
||||
mkdir -p "$WARP_APP_PATH/Contents/Frameworks"
|
||||
cp -a "$SENTRY_FRAMEWORK" "$WARP_APP_PATH/Contents/Frameworks/"
|
||||
fi
|
||||
echo "Adding rpath to support mac frameworks (e.g. Sentry)"
|
||||
@@ -126,6 +135,14 @@ if [[ ",$FEATURES," =~ ",heap_usage_tracking," ]]; then
|
||||
"${REPO_ROOT}/script/prepare_bundled_pprof" "$HELPERS_DIR"
|
||||
fi
|
||||
|
||||
if [[ ",$FEATURES," =~ ",warp_control_cli," ]]; then
|
||||
WARPCTRL_SCRIPT_PATH="$WARP_APP_PATH/Contents/Resources/bin/warpctrl-$WARP_CHANNEL"
|
||||
echo "Creating warpctrl wrapper script at $WARPCTRL_SCRIPT_PATH..."
|
||||
"${REPO_ROOT}/script/macos/create_warpctrl_wrapper" \
|
||||
"$WARPCTRL_SCRIPT_PATH" \
|
||||
"../../MacOS/$WARP_BIN_NAME"
|
||||
fi
|
||||
|
||||
echo "Codesigning app..."
|
||||
SIGNING_CERT="$(security find-identity -p codesigning -v | grep "Apple Development" | awk '{print $2}' | head -1)"
|
||||
codesign --force --deep --options runtime --sign "${SIGNING_CERT:--}" "$WARP_APP_PATH" --entitlements script/Debug-Entitlements.plist
|
||||
@@ -133,10 +150,18 @@ codesign --force --deep --options runtime --sign "${SIGNING_CERT:--}" "$WARP_APP
|
||||
if [ "$DONT_OPEN" = false ] ; then
|
||||
if [ "$OPEN_WITH_LAUNCHD" = true ]; then
|
||||
echo "Launching with MacOS application launcher"
|
||||
PATH="" /usr/bin/open "./$WARP_APP_PATH"
|
||||
tail -f ~/Library/Logs/warp_local.log
|
||||
PATH="" /usr/bin/open "$WARP_APP_PATH"
|
||||
if [ "$WARP_CHANNEL" = "local" ]; then
|
||||
LOG_FILE=~/Library/Logs/warp_local.log
|
||||
elif [ "$WARP_CHANNEL" = "oss" ]; then
|
||||
LOG_FILE=~/Library/Logs/warp-oss.log
|
||||
else
|
||||
echo "Warning: unrecognized WARP_CHANNEL '$WARP_CHANNEL', defaulting to OSS log path" >&2
|
||||
LOG_FILE=~/Library/Logs/warp-oss.log
|
||||
fi
|
||||
tail -F "$LOG_FILE"
|
||||
else
|
||||
echo "Opening app at ./$WARP_APP_PATH/Contents/MacOS/$WARP_BIN_NAME"
|
||||
"./$WARP_APP_PATH/Contents/MacOS/$WARP_BIN_NAME" "${WARP_ARGS[@]}"
|
||||
echo "Opening app at $WARP_APP_PATH/Contents/MacOS/$WARP_BIN_NAME"
|
||||
"$WARP_APP_PATH/Contents/MacOS/$WARP_BIN_NAME" "${WARP_ARGS[@]}"
|
||||
fi
|
||||
fi
|
||||
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
workspace_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
temp_dir="$(mktemp -d)"
|
||||
trap 'rm -rf "$temp_dir"' EXIT
|
||||
|
||||
bundle_dir="$temp_dir/WarpDev.app/Contents"
|
||||
wrapper_path="$bundle_dir/Resources/bin/warpctrl-dev"
|
||||
binary_path="$bundle_dir/MacOS/dev"
|
||||
installed_path="$temp_dir/usr/local/bin/warpctrl-dev"
|
||||
forwarded_args_file="$temp_dir/forwarded-args"
|
||||
expected_args_file="$temp_dir/expected-args"
|
||||
|
||||
mkdir -p "$(dirname "$binary_path")" "$(dirname "$installed_path")"
|
||||
cat > "$binary_path" << 'EOF'
|
||||
#!/bin/bash
|
||||
printf '%s\n' "$@" > "$FORWARDED_ARGS_FILE"
|
||||
EOF
|
||||
chmod +x "$binary_path"
|
||||
|
||||
"$workspace_root/script/macos/create_warpctrl_wrapper" \
|
||||
"$wrapper_path" \
|
||||
"../../MacOS/dev"
|
||||
|
||||
cat > "$expected_args_file" << 'EOF'
|
||||
--warpctrl
|
||||
tab
|
||||
create
|
||||
--instance
|
||||
inst 123
|
||||
EOF
|
||||
|
||||
FORWARDED_ARGS_FILE="$forwarded_args_file" \
|
||||
"$wrapper_path" tab create --instance "inst 123"
|
||||
cmp "$expected_args_file" "$forwarded_args_file"
|
||||
|
||||
ln -s "$wrapper_path" "$installed_path"
|
||||
FORWARDED_ARGS_FILE="$forwarded_args_file" \
|
||||
"$installed_path" tab create --instance "inst 123"
|
||||
cmp "$expected_args_file" "$forwarded_args_file"
|
||||
@@ -22,6 +22,12 @@
|
||||
# SKIP_SETTINGS_SCHEMA: Set to "1" to skip generating the JSON settings
|
||||
# schema. By default the schema is always generated
|
||||
# so that production bundles never accidentally omit it.
|
||||
# SETTINGS_SCHEMA_CACHE: Path to a cache file for the generated schema.
|
||||
# When set, the first invocation generates the schema
|
||||
# and saves a copy to this path; subsequent invocations
|
||||
# copy from the cache instead of regenerating. This
|
||||
# avoids redundant compilations when bundling multiple
|
||||
# package formats for the same channel.
|
||||
|
||||
set -e
|
||||
|
||||
@@ -84,6 +90,7 @@ fi
|
||||
# When adding a new third-party component to the bundle, add its license file
|
||||
# to the repo alongside the component and add an entry here.
|
||||
ADDITIONAL_LICENSES=(
|
||||
"Alacritty (alacritty_terminal)|Apache-2.0|crates/warp_terminal/src/model/LICENSE-ALACRITTY"
|
||||
"Hack Font|MIT|app/assets/bundled/fonts/hack/LICENSE.md"
|
||||
"Roboto Font|SIL Open Font License|app/assets/bundled/fonts/roboto/LICENSE.txt"
|
||||
"bash-preexec|MIT|app/assets/bundled/bootstrap/bash-preexec-LICENSE.md"
|
||||
@@ -123,19 +130,30 @@ fi
|
||||
# Generate settings JSON schema unless explicitly skipped.
|
||||
if [ "${SKIP_SETTINGS_SCHEMA:-}" != "1" ]; then
|
||||
SCHEMA_OUTPUT="$DEST_DIR/settings_schema.json"
|
||||
echo "Generating settings schema at $SCHEMA_OUTPUT"
|
||||
|
||||
SCHEMA_CMD=(cargo run)
|
||||
if [ -n "$CARGO_PROFILE" ]; then
|
||||
SCHEMA_CMD+=(--profile "$CARGO_PROFILE")
|
||||
fi
|
||||
SCHEMA_CMD+=(--manifest-path "$REPO_ROOT/Cargo.toml" --bin generate_settings_schema --)
|
||||
if [ -n "$CHANNEL" ]; then
|
||||
SCHEMA_CMD+=(--channel "$CHANNEL")
|
||||
fi
|
||||
SCHEMA_CMD+=("$SCHEMA_OUTPUT")
|
||||
if [ -n "${SETTINGS_SCHEMA_CACHE:-}" ] && [ -f "$SETTINGS_SCHEMA_CACHE" ]; then
|
||||
echo "Copying cached settings schema to $SCHEMA_OUTPUT"
|
||||
cp "$SETTINGS_SCHEMA_CACHE" "$SCHEMA_OUTPUT"
|
||||
else
|
||||
echo "Generating settings schema at $SCHEMA_OUTPUT"
|
||||
|
||||
"${SCHEMA_CMD[@]}"
|
||||
SCHEMA_CMD=(cargo run)
|
||||
if [ -n "$CARGO_PROFILE" ]; then
|
||||
SCHEMA_CMD+=(--profile "$CARGO_PROFILE")
|
||||
fi
|
||||
SCHEMA_CMD+=(--manifest-path "$REPO_ROOT/Cargo.toml" --bin generate_settings_schema --)
|
||||
if [ -n "$CHANNEL" ]; then
|
||||
SCHEMA_CMD+=(--channel "$CHANNEL")
|
||||
fi
|
||||
SCHEMA_CMD+=("$SCHEMA_OUTPUT")
|
||||
|
||||
"${SCHEMA_CMD[@]}"
|
||||
|
||||
if [ -n "${SETTINGS_SCHEMA_CACHE:-}" ]; then
|
||||
echo "Caching settings schema at $SETTINGS_SCHEMA_CACHE"
|
||||
cp "$SCHEMA_OUTPUT" "$SETTINGS_SCHEMA_CACHE"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Successfully prepared bundled resources in $DEST_DIR"
|
||||
|
||||
+6
-3
@@ -6,17 +6,20 @@
|
||||
set -e
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
FMT_COMMAND="cargo fmt"
|
||||
FMT_COMMAND="./script/format"
|
||||
echo "Running $FMT_COMMAND..."
|
||||
set -e
|
||||
EXIT_CODE=0
|
||||
$FMT_COMMAND -- --check || EXIT_CODE=$?
|
||||
$FMT_COMMAND --check || EXIT_CODE=$?
|
||||
if [[ $EXIT_CODE -ne 0 ]]; then
|
||||
echo 'Run `'"$FMT_COMMAND"'` to fix.'
|
||||
exit $EXIT_CODE
|
||||
fi
|
||||
|
||||
echo "Cargo fmt succeeded..."
|
||||
echo "Rust formatting succeeded..."
|
||||
echo "Checking for inline Rust test modules..."
|
||||
./script/check_no_inline_test_modules
|
||||
echo "Inline Rust test module check succeeded..."
|
||||
|
||||
echo "Running clippy..."
|
||||
# Exclude warp_completer because we run clippy on it with default features (rather than all features) below.
|
||||
|
||||
Executable
+57
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eo pipefail
|
||||
|
||||
COMMON_SKILLS_REPO="warpdotdev/common-skills"
|
||||
COMMON_SKILLS_REF="${WARP_COMMON_SKILLS_REF:-main}"
|
||||
RAW_BASE_URL="${WARP_COMMON_SKILLS_RAW_BASE_URL:-https://raw.githubusercontent.com/${COMMON_SKILLS_REPO}/${COMMON_SKILLS_REF}/scripts}"
|
||||
RESOLVER_NAME="resolve_common_skills"
|
||||
|
||||
execute_resolver_from_dir() {
|
||||
local script_path="${WARP_COMMON_SKILLS_SCRIPTS_DIR%/}/${RESOLVER_NAME}"
|
||||
|
||||
if [[ -x "${script_path}" ]]; then
|
||||
exec "${script_path}" "$@"
|
||||
fi
|
||||
|
||||
if [[ -f "${script_path}" ]]; then
|
||||
exec bash "${script_path}" "$@"
|
||||
fi
|
||||
|
||||
echo "error: could not execute ${RESOLVER_NAME} from WARP_COMMON_SKILLS_SCRIPTS_DIR=${WARP_COMMON_SKILLS_SCRIPTS_DIR}" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
execute_resolver_from_remote() {
|
||||
local raw_url="${RAW_BASE_URL%/}/${RESOLVER_NAME}"
|
||||
local temp_script=""
|
||||
local status=0
|
||||
|
||||
if ! command -v curl >/dev/null 2>&1; then
|
||||
echo "error: curl is required to fetch ${raw_url}" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
temp_script="$(mktemp "${TMPDIR:-/tmp}/common-skills-resolver.XXXXXX")"
|
||||
if curl -fsSL "${raw_url}" -o "${temp_script}"; then
|
||||
:
|
||||
else
|
||||
status=$?
|
||||
rm -f "${temp_script}"
|
||||
return "${status}"
|
||||
fi
|
||||
|
||||
if bash "${temp_script}" "$@"; then
|
||||
status=0
|
||||
else
|
||||
status=$?
|
||||
fi
|
||||
rm -f "${temp_script}"
|
||||
return "${status}"
|
||||
}
|
||||
|
||||
if [[ -n "${WARP_COMMON_SKILLS_SCRIPTS_DIR:-}" ]]; then
|
||||
execute_resolver_from_dir "$@"
|
||||
fi
|
||||
|
||||
execute_resolver_from_remote "$@"
|
||||
+35
@@ -19,9 +19,13 @@ cd "${REPO_ROOT}"
|
||||
OS_TYPE="$(uname -s)"
|
||||
|
||||
FEATURES="gui"
|
||||
INSTALL_COMMON_SKILLS=1
|
||||
FORCE_COMMON_SKILLS=0
|
||||
COMMON_SKILLS_TARGET="${WARP_COMMON_SKILLS_INSTALL_TARGET:-}"
|
||||
|
||||
./script/install_channel_config || echo "Skipping internal channel config installation (no repo access)."
|
||||
|
||||
|
||||
# If warp_channel_config is on PATH, build the Local channel binary; otherwise build the OSS channel.
|
||||
if command -v warp-channel-config &>/dev/null; then
|
||||
WARP_BIN_NAME="galaxy-local"
|
||||
@@ -63,6 +67,10 @@ while (( "$#" )); do
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
--install-common-skills)
|
||||
FORCE_COMMON_SKILLS=1
|
||||
shift
|
||||
;;
|
||||
--release)
|
||||
CARGO_PARAMS+=("$1")
|
||||
MAC_ARGS+=("$1")
|
||||
@@ -87,6 +95,33 @@ while (( "$#" )); do
|
||||
esac
|
||||
done
|
||||
|
||||
install_common_skills_or_continue() {
|
||||
if ! ./script/resolve_common_skills install_common_skills -- --repo-root "${REPO_ROOT}" "$@"; then
|
||||
echo "error: unable to install common skills; continuing without them." >&2
|
||||
fi
|
||||
}
|
||||
if [[ "$INSTALL_COMMON_SKILLS" -eq 1 ]]; then
|
||||
COMMON_SKILLS_ARGS=()
|
||||
if [[ "${COMMON_SKILLS_TARGET}" = "project" || "${COMMON_SKILLS_TARGET}" = "global" ]]; then
|
||||
COMMON_SKILLS_ARGS=("--${COMMON_SKILLS_TARGET}")
|
||||
fi
|
||||
if [[ "${WARP_SKIP_COMMON_SKILLS_INSTALL:-}" = "1" ]]; then
|
||||
:
|
||||
elif [[ "$FORCE_COMMON_SKILLS" -eq 1 ]]; then
|
||||
if [[ "${#COMMON_SKILLS_ARGS[@]}" -gt 0 ]]; then
|
||||
install_common_skills_or_continue "${COMMON_SKILLS_ARGS[@]}" --force
|
||||
else
|
||||
install_common_skills_or_continue --force --prompt-for-target
|
||||
fi
|
||||
else
|
||||
if [[ "${#COMMON_SKILLS_ARGS[@]}" -gt 0 ]]; then
|
||||
install_common_skills_or_continue "${COMMON_SKILLS_ARGS[@]}" --if-needed --quiet
|
||||
else
|
||||
install_common_skills_or_continue --if-needed --prompt-for-target --quiet
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# These cargo features were removed and replaced by environment variables read
|
||||
# by warp-channel-config. Intercept them here so that existing --features
|
||||
# invocations keep working.
|
||||
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Run a local `warp_tui` build.
|
||||
#
|
||||
# Selects the internal `local` channel when the `warp-channel-config` generator
|
||||
# is available (mirroring `./script/run`), otherwise falls back to the OSS
|
||||
# channel so contributors without repo access can still run the TUI. Unlike the
|
||||
# GUI `./script/run`, the TUI is a console binary, so there is no `.app` bundle
|
||||
# step — it just runs the appropriate `cargo` binary.
|
||||
#
|
||||
# Extra arguments are forwarded to `cargo run` (e.g. `--release`); use `--` to
|
||||
# pass arguments through to the binary itself.
|
||||
|
||||
set -e
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. && pwd)"
|
||||
cd "${REPO_ROOT}"
|
||||
|
||||
./script/install_channel_config || echo "Skipping internal channel config installation (no repo access)."
|
||||
|
||||
if command -v warp-channel-config &>/dev/null; then
|
||||
BIN="warp-tui"
|
||||
CHANNEL="local"
|
||||
else
|
||||
BIN="warp-tui-oss"
|
||||
CHANNEL="oss"
|
||||
fi
|
||||
|
||||
echo "Running cargo run -p warp_tui --bin ${BIN} (channel: ${CHANNEL})"
|
||||
exec cargo run -p warp_tui --bin "${BIN}" "$@"
|
||||
Executable
+49
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
workspace_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
discovery_dir="$(mktemp -d)"
|
||||
trap 'rm -rf "$discovery_dir"' EXIT
|
||||
|
||||
python3 - "$workspace_root" "$discovery_dir" <<'PY'
|
||||
import os
|
||||
import pathlib
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
workspace_root = pathlib.Path(sys.argv[1])
|
||||
discovery_dir = sys.argv[2]
|
||||
environment = os.environ.copy()
|
||||
environment["WARP_LOCAL_CONTROL_DISCOVERY_DIR"] = discovery_dir
|
||||
result = subprocess.run(
|
||||
[
|
||||
"cargo",
|
||||
"run",
|
||||
"-p",
|
||||
"warp",
|
||||
"--bin",
|
||||
"warp",
|
||||
"--features",
|
||||
"warp_control_cli",
|
||||
"--",
|
||||
"--warpctrl",
|
||||
"--output-format",
|
||||
"json",
|
||||
"instance",
|
||||
"list",
|
||||
],
|
||||
cwd=workspace_root,
|
||||
env=environment,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=180,
|
||||
)
|
||||
if result.returncode != 0:
|
||||
sys.stderr.write(result.stderr)
|
||||
sys.stderr.write(result.stdout)
|
||||
raise SystemExit(result.returncode)
|
||||
if result.stdout.strip() != "[]":
|
||||
sys.stderr.write(result.stderr)
|
||||
sys.stderr.write(f"unexpected warpctrl output: {result.stdout!r}\n")
|
||||
raise SystemExit(1)
|
||||
PY
|
||||
@@ -58,6 +58,7 @@ if [[ -z "$WARP_PLIST_NO_FILE_TYPES" ]]; then
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key><string>Folder</string>
|
||||
<key>CFBundleTypeRole</key><string>Editor</string>
|
||||
<key>LSHandlerRank</key><string>Alternate</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>public.folder</string>
|
||||
@@ -82,6 +83,7 @@ if [[ -z "$WARP_PLIST_NO_FILE_TYPES" ]]; then
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key><string>Markdown File</string>
|
||||
<key>CFBundleTypeRole</key><string>Editor</string>
|
||||
<key>LSHandlerRank</key><string>Alternate</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>net.daringfireball.markdown</string>
|
||||
@@ -93,6 +95,7 @@ if [[ -z "$WARP_PLIST_NO_FILE_TYPES" ]]; then
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key><string>Plain Text File</string>
|
||||
<key>CFBundleTypeRole</key><string>Editor</string>
|
||||
<key>LSHandlerRank</key><string>Alternate</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>public.plain-text</string>
|
||||
@@ -101,6 +104,7 @@ if [[ -z "$WARP_PLIST_NO_FILE_TYPES" ]]; then
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key><string>Source Code File</string>
|
||||
<key>CFBundleTypeRole</key><string>Editor</string>
|
||||
<key>LSHandlerRank</key><string>Alternate</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>public.source-code</string>
|
||||
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# script/warp_sudo - source this file to define the `warp_sudo` function.
|
||||
#
|
||||
# `warp_sudo` is a thin wrapper around `sudo` that echoes the command it
|
||||
# is about to run and asks for confirmation before invoking it. This gives
|
||||
# the user a chance to see (and decline) every privileged action taken
|
||||
# during bootstrap, which is otherwise opaque.
|
||||
#
|
||||
# Skip the prompt by setting WARP_SKIP_SUDO_PROMPT=1 (also set automatically
|
||||
# by `./script/bootstrap -y` / `--yes`) or by running with stdin not
|
||||
# attached to a tty (e.g. CI). The prompt itself is read from /dev/tty,
|
||||
# so pipes like `curl ... | warp_sudo apt-key add -` continue to work.
|
||||
|
||||
warp_sudo() {
|
||||
printf '\n>>> requires root: sudo %s\n' "$*" >&2
|
||||
|
||||
if [ "${WARP_SKIP_SUDO_PROMPT:-}" = "1" ]; then
|
||||
sudo "$@"
|
||||
return
|
||||
fi
|
||||
|
||||
# Probe for a usable controlling terminal. `[ -r /dev/tty ]` is unreliable
|
||||
# on macOS (the device file is always world-readable, even for processes
|
||||
# with no controlling tty), so actually try to open it in a subshell.
|
||||
if (: </dev/tty) 2>/dev/null; then
|
||||
# Write the prompt to /dev/tty (not stderr) so it stays visible even
|
||||
# when stderr is redirected, matching where the response is read from.
|
||||
printf ' continue? [y/N] ' >/dev/tty
|
||||
reply=""
|
||||
read -r reply </dev/tty || reply=""
|
||||
case "$reply" in
|
||||
y|Y|yes|YES) sudo "$@" ;;
|
||||
*) printf ' aborted.\n' >&2; return 1 ;;
|
||||
esac
|
||||
else
|
||||
sudo "$@"
|
||||
fi
|
||||
}
|
||||
@@ -35,11 +35,11 @@ First, ensure you've set up your environment.
|
||||
By default, it is located at `C:\Program Files (x86)\Inno Setup 6\ISCC.exe`.
|
||||
2. Compile the installer:
|
||||
```shell
|
||||
iscc .\script\windows\windows-installer.iss`.
|
||||
iscc .\script\windows\windows-installer.iss
|
||||
```
|
||||
3. Run the generated executable:
|
||||
```shell
|
||||
.\script\windows\Output\Warp-Windows-Setup.exe`.
|
||||
.\script\windows\Output\Warp-Windows-Setup.exe
|
||||
```
|
||||
|
||||
The script begins with a series of preprocessor definitions.
|
||||
|
||||
@@ -1,6 +1,80 @@
|
||||
#!/usr/bin/env powershell
|
||||
param(
|
||||
[switch]$Help,
|
||||
[switch]$InstallCommonSkills,
|
||||
[string]$CommonSkillsTarget = $env:WARP_COMMON_SKILLS_INSTALL_TARGET
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$RepoRoot = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path
|
||||
|
||||
function Show-Usage {
|
||||
Write-Output 'Usage: .\script\windows\bootstrap.ps1 [-Help] [-InstallCommonSkills] [-CommonSkillsTarget <project|global>]'
|
||||
Write-Output ''
|
||||
Write-Output 'Prepare this checkout for Warp development on Windows.'
|
||||
Write-Output ''
|
||||
Write-Output 'Options:'
|
||||
Write-Output ' -Help Show this help message.'
|
||||
Write-Output ' -InstallCommonSkills Install or update common agent skills from skills-lock.json.'
|
||||
Write-Output ' -CommonSkillsTarget Install into project .agents/skills or global ~/.agents/skills.'
|
||||
Write-Output ''
|
||||
Write-Output 'Environment:'
|
||||
Write-Output ' WARP_SKIP_COMMON_SKILLS_INSTALL=1'
|
||||
Write-Output ' Skip installing common agent skills.'
|
||||
Write-Output ' WARP_COMMON_SKILLS_INSTALL_TARGET=project|global'
|
||||
Write-Output ' Choose the install target when -CommonSkillsTarget is omitted.'
|
||||
Write-Output ' Target prompting and duplicate checks are delegated to warpdotdev/common-skills/scripts/install_common_skills.'
|
||||
Write-Output ' WARP_COMMON_SKILLS_SCRIPTS_DIR=/path/to/common-skills/scripts'
|
||||
Write-Output ' Override where common-skills management scripts are loaded from.'
|
||||
Write-Output ' WARP_COMMON_SKILLS_REF=<git-ref>'
|
||||
Write-Output ' Override the remote warpdotdev/common-skills ref used when fetching scripts.'
|
||||
}
|
||||
|
||||
function ConvertTo-CommonSkillsTarget {
|
||||
param([string]$Target)
|
||||
|
||||
switch ($Target.ToLowerInvariant()) {
|
||||
{ $_ -eq '' -or $_ -eq 'p' -or $_ -eq 'project' -or $_ -eq '1' } { return 'project' }
|
||||
{ $_ -eq 'g' -or $_ -eq 'global' -or $_ -eq '2' } { return 'global' }
|
||||
default { throw "Invalid common skills install target: $Target" }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function Show-BootstrapPreview {
|
||||
Write-Output 'Warp bootstrap is starting for Windows.'
|
||||
Write-Output 'It will:'
|
||||
Write-Output ' - Check for Git for Windows.'
|
||||
Write-Output ' - Install Rust if cargo is unavailable.'
|
||||
Write-Output ' - Install Visual Studio Build Tools, jq, CMake, InnoSetup, and gcloud as needed.'
|
||||
Write-Output ' - Install Cargo test dependencies.'
|
||||
|
||||
if (-not $InstallCommonSkills) {
|
||||
Write-Output ' - Skip common agent skills unless -InstallCommonSkills is provided.'
|
||||
} elseif ($env:WARP_SKIP_COMMON_SKILLS_INSTALL -eq '1') {
|
||||
Write-Output ' - Skip common agent skills because WARP_SKIP_COMMON_SKILLS_INSTALL=1.'
|
||||
} elseif ($script:ResolvedCommonSkillsTarget -eq 'global') {
|
||||
Write-Output ' - Install or update common agent skills in ~/.agents/skills if needed.'
|
||||
} elseif ($script:ResolvedCommonSkillsTarget -eq 'project') {
|
||||
Write-Output ' - Install or update common agent skills in this checkout''s .agents/skills if needed.'
|
||||
} else {
|
||||
Write-Output ' - Prompt for where common agent skills should be installed before installing or updating them.'
|
||||
}
|
||||
|
||||
Write-Output 'Run .\script\windows\bootstrap.ps1 -Help to see options and environment overrides.'
|
||||
Write-Output ''
|
||||
}
|
||||
|
||||
if ($Help) {
|
||||
Show-Usage
|
||||
exit 0
|
||||
}
|
||||
$script:ResolvedCommonSkillsTarget = ''
|
||||
if ($InstallCommonSkills -and $CommonSkillsTarget) {
|
||||
$script:ResolvedCommonSkillsTarget = ConvertTo-CommonSkillsTarget $CommonSkillsTarget
|
||||
}
|
||||
|
||||
Show-BootstrapPreview
|
||||
|
||||
# Git for Windows can be installed system-wide (Program Files) or per-user (LOCALAPPDATA\Programs\Git).
|
||||
$gitBinCandidates = @(
|
||||
@@ -13,6 +87,37 @@ if (-not $gitBinDir) {
|
||||
Write-Error 'https://gitforwindows.org/'
|
||||
exit 1
|
||||
}
|
||||
$env:PATH = "$gitBinDir;$env:PATH"
|
||||
function Resolve-CommonSkillsScript {
|
||||
param([string]$ScriptName)
|
||||
|
||||
if ($env:WARP_COMMON_SKILLS_SCRIPTS_DIR) {
|
||||
$scriptPath = Join-Path $env:WARP_COMMON_SKILLS_SCRIPTS_DIR $ScriptName
|
||||
if (Test-Path -PathType Leaf $scriptPath) { return $scriptPath }
|
||||
throw "Could not find $ScriptName in WARP_COMMON_SKILLS_SCRIPTS_DIR=$env:WARP_COMMON_SKILLS_SCRIPTS_DIR."
|
||||
}
|
||||
|
||||
$commonSkillsRef = if ($env:WARP_COMMON_SKILLS_REF) { $env:WARP_COMMON_SKILLS_REF } else { 'main' }
|
||||
$rawBaseUrl = if ($env:WARP_COMMON_SKILLS_RAW_BASE_URL) {
|
||||
$env:WARP_COMMON_SKILLS_RAW_BASE_URL.TrimEnd('/')
|
||||
} else {
|
||||
"https://raw.githubusercontent.com/warpdotdev/common-skills/$commonSkillsRef/scripts"
|
||||
}
|
||||
$rawUrl = "$rawBaseUrl/$ScriptName"
|
||||
$scriptPath = Join-Path $env:TEMP "warp-$ScriptName"
|
||||
|
||||
Invoke-WebRequest -Uri $rawUrl -OutFile $scriptPath
|
||||
return $scriptPath
|
||||
}
|
||||
|
||||
function Install-CommonSkill {
|
||||
$installScript = Resolve-CommonSkillsScript 'install_common_skills'
|
||||
if ($script:ResolvedCommonSkillsTarget) {
|
||||
& "$gitBinDir\bash.exe" "$installScript" --repo-root "$RepoRoot" "--$script:ResolvedCommonSkillsTarget" --if-needed
|
||||
} else {
|
||||
& "$gitBinDir\bash.exe" "$installScript" --repo-root "$RepoRoot" --if-needed --prompt-for-target
|
||||
}
|
||||
}
|
||||
|
||||
if (-not (Get-Command -Name cargo -Type Application -ErrorAction SilentlyContinue)) {
|
||||
Write-Output 'Installing rust...'
|
||||
@@ -22,6 +127,24 @@ if (-not (Get-Command -Name cargo -Type Application -ErrorAction SilentlyContinu
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Visual Studio Build Tools (MSVC compiler + linker + Windows SDK) are required to link Rust crates
|
||||
# targeting x86_64-pc-windows-msvc.
|
||||
$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
|
||||
$haveMsvcBuildTools = $false
|
||||
if (Test-Path $vswhere) {
|
||||
$vsInstall = & $vswhere -latest -products * `
|
||||
-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 Microsoft.VisualStudio.Component.Windows11SDK.22621 `
|
||||
-property installationPath
|
||||
if ($vsInstall) { $haveMsvcBuildTools = $true }
|
||||
}
|
||||
if (-not $haveMsvcBuildTools) {
|
||||
Write-Output 'Installing Visual Studio Build Tools (MSVC + Windows SDK)...'
|
||||
winget install -e --id Microsoft.VisualStudio.2022.BuildTools `
|
||||
--accept-package-agreements --accept-source-agreements `
|
||||
--override '--passive --wait --norestart --add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.VisualStudio.Component.Windows11SDK.22621 --includeRecommended'
|
||||
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||
}
|
||||
|
||||
# A bash executable should come with Git for Windows
|
||||
& "$gitBinDir\bash.exe" "$PWD\script\install_cargo_test_deps"
|
||||
|
||||
@@ -51,3 +174,7 @@ if ($identityToken.Trim().Length -eq 0) {
|
||||
Read-Host
|
||||
gcloud auth login
|
||||
}
|
||||
|
||||
if ($InstallCommonSkills) {
|
||||
Install-CommonSkill
|
||||
}
|
||||
|
||||
@@ -92,32 +92,32 @@ if ("$CHANNEL" -eq 'local') {
|
||||
$WARP_BIN = 'warp'
|
||||
$BINARY_NAME = 'warp.exe'
|
||||
$APP_NAME = 'GalaxyLocal'
|
||||
$FEATURES = "$FEATURES,nld_improvements"
|
||||
} elseif ("$CHANNEL" -eq 'dev') {
|
||||
$WARP_BIN = 'dev'
|
||||
$BINARY_NAME = 'dev.exe'
|
||||
$APP_NAME = 'GalaxyDev'
|
||||
$FEATURES = "$FEATURES,agent_mode_debug,nld_improvements"
|
||||
$FEATURES = "$FEATURES,agent_mode_debug"
|
||||
} elseif ("$CHANNEL" -eq 'preview') {
|
||||
$WARP_BIN = 'preview'
|
||||
$BINARY_NAME = 'preview.exe'
|
||||
$APP_NAME = 'GalaxyPreview'
|
||||
$FEATURES = "$FEATURES,preview_channel,nld_improvements"
|
||||
$FEATURES = "$FEATURES,preview_channel"
|
||||
} elseif ("$CHANNEL" -eq 'stable') {
|
||||
$WARP_BIN = 'stable'
|
||||
$BINARY_NAME = 'warp.exe'
|
||||
$APP_NAME = 'Galaxy'
|
||||
# TODO(vorporeal): Remove this once we get tests passing with this default enabled.
|
||||
$FEATURES = "$FEATURES,nld_improvements"
|
||||
} elseif ("$CHANNEL" -eq 'oss') {
|
||||
$WARP_BIN = 'warp-oss'
|
||||
$BINARY_NAME = 'warp-oss.exe'
|
||||
$APP_NAME = 'GalaxyOss'
|
||||
# The OSS channel does not ship Sentry, so drop the crash_reporting feature
|
||||
# (which would otherwise pull in the Sentry SDK as a dependency).
|
||||
$FEATURES = 'release_bundle,gui,nld_improvements'
|
||||
$FEATURES = 'release_bundle,gui'
|
||||
}
|
||||
|
||||
# All channels ship the v3 classifier and v2 heuristic.
|
||||
$FEATURES = "$FEATURES,nld_classifier_v3,nld_heuristic_v2"
|
||||
|
||||
$BINARY_PATH = "$CARGO_TARGET_OUTPUT_DIR\$BINARY_NAME"
|
||||
$BUNDLE_ID = "dev.warp.$APP_NAME"
|
||||
$INSTALLER_OUTPUT_DIR = "$WINDOWS_INSTALLER_DIR\Output"
|
||||
|
||||
@@ -122,6 +122,7 @@ if ($Channel -and (Test-Path $GatedSource -PathType Container)) {
|
||||
# to the repo alongside the component and add an entry here.
|
||||
# Cross-platform components:
|
||||
$AdditionalLicenses = @(
|
||||
@{ Name = 'Alacritty (alacritty_terminal)'; License = 'Apache-2.0'; Path = 'crates\warp_terminal\src\model\LICENSE-ALACRITTY' },
|
||||
@{ Name = 'Hack Font'; License = 'MIT'; Path = 'app\assets\bundled\fonts\hack\LICENSE.md' },
|
||||
@{ Name = 'Roboto Font'; License = 'SIL Open Font License'; Path = 'app\assets\bundled\fonts\roboto\LICENSE.txt' },
|
||||
@{ Name = 'bash-preexec'; License = 'MIT'; Path = 'app\assets\bundled\bootstrap\bash-preexec-LICENSE.md' },
|
||||
|
||||
@@ -70,13 +70,13 @@ UninstallDisplayIcon="{app}\icon.ico"
|
||||
CloseApplications=force
|
||||
; For manual installs: if Warp is running, show a dialog prompting the user to close it
|
||||
; before Setup proceeds. Returned empty for background updates so the check is skipped.
|
||||
; TODO(andy) uncomment this after the 4/22 release
|
||||
;AppMutex={code:GetAppMutex}
|
||||
AppMutex={code:GetAppMutex}
|
||||
SetupMutex={#AppMutexName}Setup
|
||||
; Version 1809 / Build 18362 is required for ConPTY. See https://github.com/microsoft/vscode-docs/blob/9d736b662fdde3fed17d8bc2ed70bfea4ae20636/docs/supporting/troubleshoot-terminal-launch.md?plain=1#L66/
|
||||
MinVersion=10.0.18362
|
||||
; Tell Windows Explorer to reload the environment so that path changes take effect.
|
||||
ChangesEnvironment=true
|
||||
RedirectionGuard=no
|
||||
; Sign the setup engine and uninstaller so that the temporary bootstrapper
|
||||
; extracted to %TEMP% is Authenticode-signed. This prevents Microsoft Defender
|
||||
; ASR rule D4F940AB from blocking the installer in enterprise environments.
|
||||
@@ -109,6 +109,8 @@ Source: "{#TargetProfileDir}\resources\*"; DestDir: "{app}\resources"; Flags: ig
|
||||
|
||||
[Registry]
|
||||
Root: HKCU; Subkey: "SOFTWARE\Warp.dev\{#MyAppName}"; Flags: uninsdeletekey
|
||||
Root: HKCU; Subkey: "SOFTWARE\Warp.dev\{#MyAppName}"; ValueType: string; ValueName: "InstallationPath"; ValueData: "{app}\{#MyAppExeName}"; Flags: uninsdeletevalue
|
||||
Root: HKA; Subkey: "Software\Microsoft\Windows\CurrentVersion\App Paths\{#MyAppExeName}"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName}"; Flags: uninsdeletekey
|
||||
; cleanup "Open Warp Here" registry entries
|
||||
Root: HKA; Subkey: "Software\Classes\Directory\shell\{#MyAppName}"; Flags: deletekey
|
||||
Root: HKA; Subkey: "Software\Classes\Directory\Background\shell\{#MyAppName}"; Flags: deletekey
|
||||
@@ -212,7 +214,19 @@ begin
|
||||
Sleep(1000);
|
||||
end
|
||||
else
|
||||
begin
|
||||
Log('Warp has exited; proceeding with file installation.');
|
||||
{ The minidump crash-reporter is a child process (same exe name) that
|
||||
may outlive the main Warp process. It holds the executable file open,
|
||||
which causes the file-copy step to fail with "Access is denied".
|
||||
We identify it by the "minidump-server" argument in its command line. }
|
||||
Exec('powershell.exe',
|
||||
'-NoProfile -NoLogo -Command "$stopError = 0; Get-CimInstance Win32_Process -Filter \"Name=''{#MyAppExeName}'' and CommandLine like ''%minidump-server%''\" | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorVariable e -ErrorAction SilentlyContinue; if ($e) { $stopError = $e[0].Exception.HResult } }; exit $stopError"',
|
||||
'', SW_HIDE, ewWaitUntilTerminated, ResultCode);
|
||||
if ResultCode <> 0 then
|
||||
Log('minidump-server cleanup failed (exit code: ' + IntToStr(ResultCode) + ')');
|
||||
Sleep(500);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user