mirror of
https://github.com/warpdotdev/warp.git
synced 2026-05-07 23:58:47 +08:00
## Description The release bundling workflow runs `prepare_bundled_resources` after the main `cargo build`, and that script in turn invokes `cargo run --bin generate_settings_schema`. Until now we passed neither `--features` nor `--target` to this run, so cargo's resolver-v2 saw a different per-package feature unification than the main build and recompiled every dependency whose enabled features differed (`rust-embed` with `debug-embed`, `warp_core`'s `release_bundle`, sentry, jemalloc, etc.). This added significant time to release builds and pulled in extra system dependencies (e.g. protoc) for jobs that should otherwise just be packaging the prebuilt binary. There was a secondary correctness issue: the schema generator iterates settings registered via `inventory::submit!`, and `#[cfg(feature = \"...\")]`-gated settings were silently omitted from the schema in any context whose feature set didn't match the main binary. The fix threads the build's feature set (and target, where applicable) through to the schema-generator invocation, and makes package selection explicit with `-p warp`. With matching features and target, cargo reuses the existing compilation artifacts; with the same feature set, the generated schema is also faithful to what the bundled binary actually exposes. ## Testing Verified `bash -n` syntax for the modified bash scripts and parsed the modified PowerShell files via `pwsh`. Bundling, schema generation, and CI behavior will be exercised by this PR's release builds. ## Agent Mode - [x] Warp Agent Mode - This PR was created via Warp's AI Agent Mode [Conversation](https://staging.warp.dev/conversation/1bd5574f-df28-4c2e-867d-40d71ed7e827)
298 lines
8.7 KiB
Bash
Executable File
298 lines
8.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Builds a Warp binary and bundles it up for distribution.
|
|
|
|
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
|
|
# process.
|
|
if [ -d "$DIST_DIR" ]; then
|
|
rm -rf "$DIST_DIR"
|
|
fi
|
|
}
|
|
|
|
# Run cleanup() when the script terminates (whether it succeeded or failed).
|
|
trap cleanup EXIT
|
|
|
|
# By default we build dev bundles.
|
|
RELEASE_CHANNEL="dev"
|
|
FEATURES="release_bundle,crash_reporting"
|
|
PACKAGES=( appimage )
|
|
BUILD="true"
|
|
BUILD_ARCH="$(uname -m)"
|
|
DEBUG=false
|
|
ARTIFACT="app"
|
|
|
|
# Cache all params so we can pass them to downstream scripts.
|
|
ALL_PARAMS=$@
|
|
|
|
PARAMS=""
|
|
while (( "$#" )); do
|
|
case "$1" in
|
|
--debug)
|
|
DEBUG=true
|
|
shift
|
|
;;
|
|
--check-only)
|
|
echo 'Only running `cargo check` and not producing a bundle.'
|
|
CHECK_ONLY="true"
|
|
shift
|
|
;;
|
|
--skip-build)
|
|
BUILD="false"
|
|
shift
|
|
;;
|
|
--nouniversal)
|
|
# Discard the --nouniversal argument, which is only used for macOS
|
|
# bundles.
|
|
shift
|
|
;;
|
|
-c|--channel)
|
|
if [ -n "$2" ] && [ "${2:0:1}" != "-" ]; then
|
|
RELEASE_CHANNEL=$2
|
|
shift 2
|
|
else
|
|
echo "Error: Argument for $1 is missing" >&2
|
|
exit 1
|
|
fi
|
|
;;
|
|
--release-tag)
|
|
if [ -n "$2" ] && [ "${2:0:1}" != "-" ]; then
|
|
echo "Setting release tag to $2"
|
|
export GIT_RELEASE_TAG=$2
|
|
shift 2
|
|
else
|
|
echo "Error: Argument for $1 is missing" >&2
|
|
exit 1
|
|
fi
|
|
;;
|
|
--packages)
|
|
PACKAGES=( $(IFS=, ; echo $2) )
|
|
shift 2
|
|
;;
|
|
--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
|
|
exit 1
|
|
fi
|
|
ARTIFACT="$2"
|
|
shift 2
|
|
else
|
|
echo "Error: Argument for $1 is missing" >&2
|
|
exit 1
|
|
fi
|
|
;;
|
|
--arch)
|
|
if [ -n "$2" ]; then
|
|
if [ "$2" = "aarch64" -o "$2" = "x86_64" ]; then
|
|
echo "Setting architecture to $2"
|
|
export BUILD_ARCH=$2
|
|
shift 2
|
|
else
|
|
echo "Error: Argument for $1 is invalid; got '$2' but expected 'aarch64' or 'x86_64'." >&2
|
|
exit 1
|
|
fi
|
|
else
|
|
echo "Error: Argument for $1 is missing" >&2
|
|
exit 1
|
|
fi
|
|
;;
|
|
*) # preserve positional arguments
|
|
PARAMS="$PARAMS $1"
|
|
shift
|
|
;;
|
|
esac
|
|
done
|
|
# set positional arguments in their proper place
|
|
eval set -- "$PARAMS"
|
|
|
|
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
|
|
CARGO_PROFILE="release-cli-debug_assertions"
|
|
else
|
|
CARGO_PROFILE="release-lto-debug_assertions"
|
|
fi
|
|
else
|
|
if [[ "$ARTIFACT" == "cli" ]]; then
|
|
CARGO_PROFILE="release-cli"
|
|
else
|
|
CARGO_PROFILE="release-lto"
|
|
fi
|
|
fi
|
|
|
|
if [[ "$CARGO_PROFILE" == "dev" ]]; then
|
|
CARGO_TARGET_OUTPUT_DIR="$CARGO_TARGET_DIR/debug"
|
|
else
|
|
CARGO_TARGET_OUTPUT_DIR="$CARGO_TARGET_DIR/$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
|
|
# stale packages left in the shared Namespace runner cache.
|
|
OUT_DIR="$CARGO_TARGET_OUTPUT_DIR/bundle/linux"
|
|
mkdir -p "$OUT_DIR"
|
|
|
|
# Update parameters based on the target release channel.
|
|
#
|
|
# APP_NAME here must match the value used in Rust as the
|
|
# application name; see app/src/channel.rs.
|
|
#
|
|
# WARP_BIN is the name of the binary produced by cargo;
|
|
# BINARY_NAME is the desired name of the binary in the final package.
|
|
if [[ $RELEASE_CHANNEL = "local" ]]; then
|
|
WARP_BIN="warp"
|
|
BINARY_NAME="warp-local"
|
|
APP_NAME="WarpLocal"
|
|
FEATURES="$FEATURES,agent_mode_debug"
|
|
export HANDLE_MARKDOWN=1
|
|
elif [[ $RELEASE_CHANNEL = "dev" ]]; then
|
|
WARP_BIN="dev"
|
|
BINARY_NAME="warp-dev"
|
|
APP_NAME="WarpDev"
|
|
FEATURES="$FEATURES,agent_mode_debug"
|
|
# Enable heap profiling using jemalloc through pprof.
|
|
FEATURES="$FEATURES,jemalloc_pprof"
|
|
export HANDLE_MARKDOWN=1
|
|
elif [[ $RELEASE_CHANNEL = "preview" ]]; then
|
|
WARP_BIN="preview"
|
|
BINARY_NAME="warp-preview"
|
|
APP_NAME="WarpPreview"
|
|
FEATURES="$FEATURES,preview_channel"
|
|
elif [[ $RELEASE_CHANNEL = "stable" ]]; then
|
|
WARP_BIN="stable"
|
|
BINARY_NAME="warp"
|
|
APP_NAME="Warp"
|
|
elif [[ $RELEASE_CHANNEL = "oss" ]]; then
|
|
WARP_BIN="warp-oss"
|
|
BINARY_NAME="warp-oss"
|
|
APP_NAME="WarpOss"
|
|
# 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"
|
|
fi
|
|
|
|
# Artifact-specific binary naming
|
|
if [[ "$ARTIFACT" == "cli" ]]; then
|
|
# For CLI artifacts, use oz instead of warp as the binary name. The OSS
|
|
# channel is an exception: its CLI command name is `warp-oss`, matching
|
|
# `Channel::cli_command_name` in the Rust source.
|
|
if [[ $RELEASE_CHANNEL != "oss" ]]; then
|
|
BINARY_NAME="${BINARY_NAME/warp/oz}"
|
|
fi
|
|
fi
|
|
|
|
# Artifact-specific configuration
|
|
if [[ "$ARTIFACT" == "cli" ]]; then
|
|
FEATURES="$FEATURES,standalone"
|
|
elif [[ "$ARTIFACT" == "app" ]]; then
|
|
FEATURES="$FEATURES,gui,nld_improvements"
|
|
fi
|
|
|
|
BUNDLE_ID="dev.warp.$APP_NAME"
|
|
EXECUTABLE_PATH="$CARGO_TARGET_OUTPUT_DIR/$WARP_BIN"
|
|
DEBUG_EXECUTABLE_PATH="$EXECUTABLE_PATH.debug"
|
|
|
|
# Note that this variable must be set (and exported!) before we compile the
|
|
# binary, as it is read at compile time by Linux autoupdate logic (to know the
|
|
# expected name of the AppImage when downloading updates).
|
|
export APPIMAGE_NAME="$APP_NAME-$BUILD_ARCH.AppImage"
|
|
|
|
# If we only want to check that compilation will succeed, perform the checks
|
|
# 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"
|
|
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"
|
|
echo "Making debug copy of '$EXECUTABLE_PATH' at '$DEBUG_EXECUTABLE_PATH'"
|
|
cp "$EXECUTABLE_PATH" "$DEBUG_EXECUTABLE_PATH"
|
|
|
|
echo "Stripping debug symbols from '$EXECUTABLE_PATH'"
|
|
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"
|
|
else
|
|
# For production builds, strip all symbols, to keep the binary size
|
|
# smaller.
|
|
strip --strip-all "$EXECUTABLE_PATH"
|
|
fi
|
|
else
|
|
echo 'Skipping `cargo build` step due to --skip-build argument'
|
|
fi
|
|
|
|
# Prepare bundled resources for CLI builds.
|
|
if [[ "$ARTIFACT" == "cli" ]]; 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" "$FEATURES"
|
|
fi
|
|
|
|
|
|
# If this is being run within a GitHub action, set an output variable with the
|
|
# location of the binary so it can be referenced by subsequent actions, as well
|
|
# as the directory containing all built packages.
|
|
if [ "${GITHUB_ACTIONS}" == "true" ]; then
|
|
echo "::echo::on"
|
|
echo "executable_path=$EXECUTABLE_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"
|
|
echo "::echo::off"
|
|
fi
|
|
|
|
# Make sure a variety of environment variables are available in downstream scripts.
|
|
export \
|
|
WORKSPACE_ROOT_DIR \
|
|
DIST_DIR \
|
|
CARGO_TARGET_OUTPUT_DIR \
|
|
OUT_DIR \
|
|
RELEASE_CHANNEL \
|
|
BUNDLE_ID \
|
|
EXECUTABLE_PATH \
|
|
BINARY_NAME \
|
|
APPIMAGE_NAME \
|
|
BUILD_ARCH \
|
|
ARTIFACT \
|
|
CARGO_PROFILE \
|
|
FEATURES
|
|
|
|
# Build the AppImage bundle.
|
|
if [[ ${PACKAGES[@]} =~ "appimage" ]]; then
|
|
echo "Building AppImage..."
|
|
"$WORKSPACE_ROOT_DIR/script/linux/bundle_appimage"
|
|
fi
|
|
|
|
# Build the .deb package.
|
|
if [[ ${PACKAGES[@]} =~ "deb" ]]; then
|
|
echo "Building .deb package..."
|
|
"$WORKSPACE_ROOT_DIR/script/linux/bundle_deb"
|
|
fi
|
|
|
|
# Build the .rpm package.
|
|
if [[ ${PACKAGES[@]} =~ "rpm" ]]; then
|
|
echo "Building .rpm package..."
|
|
"$WORKSPACE_ROOT_DIR/script/linux/bundle_rpm"
|
|
fi
|
|
|
|
# Build the Arch Linux package.
|
|
if [[ ${PACKAGES[@]} =~ "arch" ]]; then
|
|
echo "Building Arch Linux package..."
|
|
"$WORKSPACE_ROOT_DIR/script/linux/bundle_arch"
|
|
fi
|