attempt to build CLI native for Windows (#3058)

This commit is contained in:
Max Novich
2025-06-24 15:33:06 -07:00
committed by GitHub
parent 0fbc69191c
commit 566796f767
4 changed files with 313 additions and 48 deletions

View File

@@ -1,7 +1,12 @@
# This is a **reuseable** workflow that bundles the Desktop App for macOS. # This is a **reuseable** workflow that builds the CLI for multiple platforms.
# It doesn't get triggered on its own. It gets used in multiple workflows: # It doesn't get triggered on its own. It gets used in multiple workflows:
# - release.yml # - release.yml
# - canary.yml # - canary.yml
#
# Platform Build Strategy:
# - Linux: Uses Ubuntu runner with cross-compilation
# - macOS: Uses macOS runner with cross-compilation
# - Windows: Uses Ubuntu runner with Docker cross-compilation (same as desktop build)
on: on:
workflow_call: workflow_call:
inputs: inputs:
@@ -9,17 +14,6 @@ on:
required: false required: false
default: "" default: ""
type: string type: string
# Let's allow overriding the OSes and architectures in JSON array form:
# e.g. '["ubuntu-latest","macos-latest"]'
# If no input is provided, these defaults apply.
operating-systems:
type: string
required: false
default: '["ubuntu-latest","macos-latest"]'
architectures:
type: string
required: false
default: '["x86_64","aarch64"]'
ref: ref:
type: string type: string
required: false required: false
@@ -30,17 +24,40 @@ name: "Reusable workflow to build CLI"
jobs: jobs:
build-cli: build-cli:
name: Build CLI name: Build CLI
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.build-on }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: ${{ fromJson(inputs.operating-systems) }}
architecture: ${{ fromJson(inputs.architectures) }}
include: include:
# Linux builds
- os: ubuntu-latest - os: ubuntu-latest
architecture: x86_64
target-suffix: unknown-linux-gnu target-suffix: unknown-linux-gnu
build-on: ubuntu-latest
use-cross: true
- os: ubuntu-latest
architecture: aarch64
target-suffix: unknown-linux-gnu
build-on: ubuntu-latest
use-cross: true
# macOS builds
- os: macos-latest - os: macos-latest
architecture: x86_64
target-suffix: apple-darwin target-suffix: apple-darwin
build-on: macos-latest
use-cross: true
- os: macos-latest
architecture: aarch64
target-suffix: apple-darwin
build-on: macos-latest
use-cross: true
# Windows builds (only x86_64 supported)
- os: windows
architecture: x86_64
target-suffix: pc-windows-gnu
build-on: ubuntu-latest
use-cross: false
use-docker: true
steps: steps:
- name: Checkout code - name: Checkout code
@@ -56,6 +73,7 @@ jobs:
rm -f Cargo.toml.bak rm -f Cargo.toml.bak
- name: Install cross - name: Install cross
if: matrix.use-cross
run: source ./bin/activate-hermit && cargo install cross --git https://github.com/cross-rs/cross run: source ./bin/activate-hermit && cargo install cross --git https://github.com/cross-rs/cross
# Install Go for building temporal-service # Install Go for building temporal-service
@@ -64,7 +82,32 @@ jobs:
with: with:
go-version: '1.21' go-version: '1.21'
- name: Build CLI # Cache Cargo registry and git dependencies for Windows builds
- name: Cache Cargo registry (Windows)
if: matrix.use-docker
uses: actions/cache@2f8e54208210a422b2efd51efaa6bd6d7ca8920f
with:
path: |
~/.cargo/registry/index
~/.cargo/registry/cache
~/.cargo/git/db
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-registry-
# Cache compiled dependencies (target/release/deps) for Windows builds
- name: Cache Cargo build (Windows)
if: matrix.use-docker
uses: actions/cache@2f8e54208210a422b2efd51efaa6bd6d7ca8920f
with:
path: target
key: ${{ runner.os }}-cargo-build-${{ hashFiles('Cargo.lock') }}-${{ hashFiles('rust-toolchain.toml') }}
restore-keys: |
${{ runner.os }}-cargo-build-${{ hashFiles('Cargo.lock') }}-
${{ runner.os }}-cargo-build-
- name: Build CLI (Linux/macOS)
if: matrix.use-cross
env: env:
CROSS_NO_WARNINGS: 0 CROSS_NO_WARNINGS: 0
RUST_LOG: debug RUST_LOG: debug
@@ -83,7 +126,102 @@ jobs:
echo "Building with explicit PROTOC path..." echo "Building with explicit PROTOC path..."
cross build --release --target ${TARGET} -p goose-cli -vv cross build --release --target ${TARGET} -p goose-cli -vv
- name: Build temporal-service for target platform using build.sh script - name: Build CLI (Windows)
if: matrix.use-docker
run: |
echo "🚀 Building Windows CLI executable with enhanced GitHub Actions caching..."
# Create cache directories
mkdir -p ~/.cargo/registry ~/.cargo/git
# Use enhanced caching with GitHub Actions cache mounts
docker run --rm \
-v "$(pwd)":/usr/src/myapp \
-v "$HOME/.cargo/registry":/usr/local/cargo/registry \
-v "$HOME/.cargo/git":/usr/local/cargo/git \
-w /usr/src/myapp \
rust:latest \
bash -c "
set -e
echo '=== Setting up Rust environment with caching ==='
export CARGO_HOME=/usr/local/cargo
export PATH=/usr/local/cargo/bin:\$PATH
# Check if Windows target is already installed in cache
if rustup target list --installed | grep -q x86_64-pc-windows-gnu; then
echo '✅ Windows cross-compilation target already installed'
else
echo '📦 Installing Windows cross-compilation target...'
rustup target add x86_64-pc-windows-gnu
fi
echo '=== Setting up build dependencies ==='
apt-get update
apt-get install -y mingw-w64 protobuf-compiler cmake time
echo '=== Setting up cross-compilation environment ==='
export CC_x86_64_pc_windows_gnu=x86_64-w64-mingw32-gcc
export CXX_x86_64_pc_windows_gnu=x86_64-w64-mingw32-g++
export AR_x86_64_pc_windows_gnu=x86_64-w64-mingw32-ar
export CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER=x86_64-w64-mingw32-gcc
export PKG_CONFIG_ALLOW_CROSS=1
export PROTOC=/usr/bin/protoc
echo '=== Optimized Cargo configuration ==='
mkdir -p .cargo
echo '[build]' > .cargo/config.toml
echo 'jobs = 4' >> .cargo/config.toml
echo '' >> .cargo/config.toml
echo '[target.x86_64-pc-windows-gnu]' >> .cargo/config.toml
echo 'linker = \"x86_64-w64-mingw32-gcc\"' >> .cargo/config.toml
echo '' >> .cargo/config.toml
echo '[net]' >> .cargo/config.toml
echo 'git-fetch-with-cli = true' >> .cargo/config.toml
echo 'retry = 3' >> .cargo/config.toml
echo '' >> .cargo/config.toml
echo '[profile.release]' >> .cargo/config.toml
echo 'codegen-units = 1' >> .cargo/config.toml
echo 'lto = false' >> .cargo/config.toml
echo 'panic = \"abort\"' >> .cargo/config.toml
echo 'debug = false' >> .cargo/config.toml
echo 'opt-level = 2' >> .cargo/config.toml
echo '' >> .cargo/config.toml
echo '[registries.crates-io]' >> .cargo/config.toml
echo 'protocol = \"sparse\"' >> .cargo/config.toml
echo '=== Building with cached dependencies ==='
# Check if we have cached build artifacts
if [ -d target/x86_64-pc-windows-gnu/release/deps ] && [ \"\$(ls -A target/x86_64-pc-windows-gnu/release/deps)\" ]; then
echo '✅ Found cached build artifacts, performing incremental build...'
CARGO_INCREMENTAL=1
else
echo '🔨 No cached artifacts found, performing full build...'
CARGO_INCREMENTAL=0
fi
echo '🔨 Building Windows CLI executable...'
CARGO_INCREMENTAL=\$CARGO_INCREMENTAL \
CARGO_NET_RETRY=3 \
CARGO_HTTP_TIMEOUT=60 \
RUST_BACKTRACE=1 \
cargo build --release --target x86_64-pc-windows-gnu -p goose-cli --jobs 4
echo '✅ Build completed successfully!'
ls -la target/x86_64-pc-windows-gnu/release/
"
# Verify build succeeded
if [ ! -f "./target/x86_64-pc-windows-gnu/release/goose.exe" ]; then
echo "❌ Windows CLI binary not found."
ls -la ./target/x86_64-pc-windows-gnu/release/ || echo "Release directory doesn't exist"
exit 1
fi
echo "✅ Windows CLI binary found!"
ls -la ./target/x86_64-pc-windows-gnu/release/goose.exe
- name: Build temporal-service for target platform using build.sh script (Linux/macOS)
if: matrix.use-cross
run: | run: |
source ./bin/activate-hermit source ./bin/activate-hermit
export TARGET="${{ matrix.architecture }}-${{ matrix.target-suffix }}" export TARGET="${{ matrix.architecture }}-${{ matrix.target-suffix }}"
@@ -124,7 +262,28 @@ jobs:
mv "${BINARY_NAME}" "../target/${TARGET}/release/${BINARY_NAME}" mv "${BINARY_NAME}" "../target/${TARGET}/release/${BINARY_NAME}"
echo "temporal-service built successfully for ${TARGET}" echo "temporal-service built successfully for ${TARGET}"
- name: Package CLI with temporal-service - name: Build temporal-service for Windows
if: matrix.use-docker
run: |
echo "Building temporal-service for Windows using build.sh script..."
docker run --rm \
-v "$(pwd)":/usr/src/myapp \
-w /usr/src/myapp/temporal-service \
golang:latest \
sh -c "
# Make build.sh executable
chmod +x build.sh
# Set Windows build environment and run build script
GOOS=windows GOARCH=amd64 ./build.sh
"
# Move the built binary to the expected location
mkdir -p target/x86_64-pc-windows-gnu/release
mv temporal-service/temporal-service.exe target/x86_64-pc-windows-gnu/release/temporal-service.exe
echo "temporal-service.exe built successfully for Windows"
- name: Package CLI with temporal-service (Linux/macOS)
if: matrix.use-cross
run: | run: |
source ./bin/activate-hermit source ./bin/activate-hermit
export TARGET="${{ matrix.architecture }}-${{ matrix.target-suffix }}" export TARGET="${{ matrix.architecture }}-${{ matrix.target-suffix }}"
@@ -141,6 +300,23 @@ jobs:
tar -cjf "goose-${TARGET}.tar.bz2" -C goose-package . tar -cjf "goose-${TARGET}.tar.bz2" -C goose-package .
echo "ARTIFACT=target/${TARGET}/release/goose-${TARGET}.tar.bz2" >> $GITHUB_ENV echo "ARTIFACT=target/${TARGET}/release/goose-${TARGET}.tar.bz2" >> $GITHUB_ENV
- name: Package CLI with temporal-service (Windows)
if: matrix.use-docker
run: |
export TARGET="${{ matrix.architecture }}-${{ matrix.target-suffix }}"
# Create a directory for the package contents
mkdir -p "target/${TARGET}/release/goose-package"
# Copy binaries
cp "target/${TARGET}/release/goose.exe" "target/${TARGET}/release/goose-package/"
cp "target/${TARGET}/release/temporal-service.exe" "target/${TARGET}/release/goose-package/"
# Create the zip archive with both binaries (Windows uses zip instead of tar.bz2)
cd "target/${TARGET}/release"
zip -r "goose-${TARGET}.zip" goose-package/
echo "ARTIFACT=target/${TARGET}/release/goose-${TARGET}.zip" >> $GITHUB_ENV
- name: Upload CLI artifact - name: Upload CLI artifact
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # pin@v4 uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # pin@v4
with: with:

View File

@@ -89,6 +89,7 @@ jobs:
- [📦 Linux (aarch64)](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/goose-aarch64-unknown-linux-gnu.zip) - [📦 Linux (aarch64)](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/goose-aarch64-unknown-linux-gnu.zip)
- [📦 macOS (x86_64)](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/goose-x86_64-apple-darwin.zip) - [📦 macOS (x86_64)](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/goose-x86_64-apple-darwin.zip)
- [📦 macOS (aarch64)](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/goose-aarch64-apple-darwin.zip) - [📦 macOS (aarch64)](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/goose-aarch64-apple-darwin.zip)
- [📦 Windows (x86_64)](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/goose-x86_64-pc-windows-gnu.zip)
These links are provided by nightly.link and will work even if you're not logged into GitHub. These links are provided by nightly.link and will work even if you're not logged into GitHub.

View File

@@ -142,7 +142,32 @@ import LinuxDesktopInstallButtons from '@site/src/components/LinuxDesktopInstall
</div> </div>
</TabItem> </TabItem>
<TabItem value="cli" label="Goose CLI"> <TabItem value="cli" label="Goose CLI">
There isn't native installation support for Windows CLI, however you can run Goose using WSL (Windows Subsystem for Linux). Install the Goose CLI directly from the browser using our download script, or use WSL for a Linux-like experience.
<h3 style={{ marginTop: '1rem' }}>Option 1: Native Windows CLI (Recommended)</h3>
Run the following command in **Git Bash**, **MSYS2**, or **PowerShell** to install the latest version of Goose natively on Windows:
```bash
curl -fsSL https://github.com/block/goose/releases/download/stable/download_cli.sh | bash
```
This script will fetch the latest version of Goose and set it up on your system.
If you'd like to install without interactive configuration, disable `CONFIGURE`:
```bash
curl -fsSL https://github.com/block/goose/releases/download/stable/download_cli.sh | CONFIGURE=false bash
```
:::note Prerequisites
- **Git Bash** (recommended): Comes with [Git for Windows](https://git-scm.com/download/win)
- **MSYS2**: Available from [msys2.org](https://www.msys2.org/)
- **PowerShell**: Available on Windows 10/11 by default
The script requires `curl` and `unzip` to be available in your environment.
:::
<h3>Option 2: Windows Subsystem for Linux (WSL)</h3>
If you prefer a Linux-like environment, you can run Goose using WSL:
1. Open [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows) as Administrator and install WSL and the default Ubuntu distribution: 1. Open [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows) as Administrator and install WSL and the default Ubuntu distribution:
@@ -193,7 +218,7 @@ Goose works with a set of [supported LLM providers][providers], and you'll need
Upon installing, Goose will automatically enter its configuration screen. Here is where you can set up your LLM provider. Upon installing, Goose will automatically enter its configuration screen. Here is where you can set up your LLM provider.
:::tip Windows Users :::tip Windows Users
Choose to not store to keyring when prompted. When using the native Windows CLI, choose to not store to keyring when prompted during initial configuration.
::: :::
Example: Example:
@@ -221,6 +246,12 @@ Goose works with a set of [supported LLM providers][providers], and you'll need
:::info Windows Users :::info Windows Users
On initial run, you may encounter errors about keyrings when setting your API Keys. Set the needed environment variables manually, e.g.: On initial run, you may encounter errors about keyrings when setting your API Keys. Set the needed environment variables manually, e.g.:
**For Native Windows CLI (Git Bash/MSYS2):**
```bash
export OPENAI_API_KEY={your_api_key}
```
**For WSL:**
```bash ```bash
export OPENAI_API_KEY={your_api_key} export OPENAI_API_KEY={your_api_key}
``` ```
@@ -231,8 +262,17 @@ Goose works with a set of [supported LLM providers][providers], and you'll need
● OPENAI_API_KEY is set via environment variable ● OPENAI_API_KEY is set via environment variable
``` ```
To make the changes persist in WSL across sessions, add the goose path and export commands to your `.bashrc` or `.bash_profile` file so you can load it later. **To make the changes persist across sessions:**
**For Native Windows CLI (Git Bash):**
Add the goose path and export commands to your `~/.bashrc` or `~/.bash_profile` file:
```bash
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
echo 'export OPENAI_API_KEY=your_api_key' >> ~/.bashrc
source ~/.bashrc
```
**For WSL:**
```bash ```bash
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
echo 'export OPENAI_API_KEY=your_api_key' >> ~/.bashrc echo 'export OPENAI_API_KEY=your_api_key' >> ~/.bashrc

View File

@@ -7,7 +7,7 @@ set -eu
# This script downloads the latest stable 'goose' CLI binary from GitHub releases # This script downloads the latest stable 'goose' CLI binary from GitHub releases
# and installs it to your system. # and installs it to your system.
# #
# Supported OS: macOS (darwin), Linux # Supported OS: macOS (darwin), Linux, Windows (MSYS2/Git Bash/WSL)
# Supported Architectures: x86_64, arm64 # Supported Architectures: x86_64, arm64
# #
# Usage: # Usage:
@@ -29,9 +29,9 @@ if ! command -v curl >/dev/null 2>&1; then
exit 1 exit 1
fi fi
# Check for tar # Check for tar or unzip (depending on OS)
if ! command -v tar >/dev/null 2>&1; then if ! command -v tar >/dev/null 2>&1 && ! command -v unzip >/dev/null 2>&1; then
echo "Error: 'tar' is required to download Goose. Please install tar and try again." echo "Error: Either 'tar' or 'unzip' is required to extract Goose. Please install one and try again."
exit 1 exit 1
fi fi
@@ -48,10 +48,14 @@ CONFIGURE="${CONFIGURE:-true}"
OS=$(uname -s | tr '[:upper:]' '[:lower:]') OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m) ARCH=$(uname -m)
# Handle Windows environments (MSYS2, Git Bash, Cygwin, WSL)
case "$OS" in case "$OS" in
linux|darwin) ;; linux|darwin) ;;
mingw*|msys*|cygwin*)
OS="windows"
;;
*) *)
echo "Error: Unsupported OS '$OS'. Goose currently only supports Linux and macOS." echo "Error: Unsupported OS '$OS'. Goose currently supports Linux, macOS, and Windows."
exit 1 exit 1
;; ;;
esac esac
@@ -73,8 +77,19 @@ esac
# Build the filename and URL for the stable release # Build the filename and URL for the stable release
if [ "$OS" = "darwin" ]; then if [ "$OS" = "darwin" ]; then
FILE="goose-$ARCH-apple-darwin.tar.bz2" FILE="goose-$ARCH-apple-darwin.tar.bz2"
EXTRACT_CMD="tar"
elif [ "$OS" = "windows" ]; then
# Windows only supports x86_64 currently
if [ "$ARCH" != "x86_64" ]; then
echo "Error: Windows currently only supports x86_64 architecture."
exit 1
fi
FILE="goose-$ARCH-pc-windows-gnu.zip"
EXTRACT_CMD="unzip"
OUT_FILE="goose.exe"
else else
FILE="goose-$ARCH-unknown-linux-gnu.tar.bz2" FILE="goose-$ARCH-unknown-linux-gnu.tar.bz2"
EXTRACT_CMD="tar"
fi fi
DOWNLOAD_URL="https://github.com/$REPO/releases/download/$RELEASE_TAG/$FILE" DOWNLOAD_URL="https://github.com/$REPO/releases/download/$RELEASE_TAG/$FILE"
@@ -97,12 +112,13 @@ trap 'rm -rf "$TMP_DIR"' EXIT
echo "Extracting $FILE to temporary directory..." echo "Extracting $FILE to temporary directory..."
set +e # Disable immediate exit on error set +e # Disable immediate exit on error
tar -xjf "$FILE" -C "$TMP_DIR" 2> tar_error.log
tar_exit_code=$?
set -e # Re-enable immediate exit on error
# Check for tar errors if [ "$EXTRACT_CMD" = "tar" ]; then
if [ $tar_exit_code -ne 0 ]; then tar -xjf "$FILE" -C "$TMP_DIR" 2> tar_error.log
extract_exit_code=$?
# Check for tar errors
if [ $extract_exit_code -ne 0 ]; then
if grep -iEq "missing.*bzip2|bzip2.*missing|bzip2.*No such file|No such file.*bzip2" tar_error.log; then if grep -iEq "missing.*bzip2|bzip2.*missing|bzip2.*No such file|No such file.*bzip2" tar_error.log; then
echo "Error: Failed to extract $FILE. 'bzip2' is required but not installed. See details below:" echo "Error: Failed to extract $FILE. 'bzip2' is required but not installed. See details below:"
else else
@@ -111,13 +127,33 @@ if [ $tar_exit_code -ne 0 ]; then
cat tar_error.log cat tar_error.log
rm tar_error.log rm tar_error.log
exit 1 exit 1
fi fi
rm tar_error.log rm tar_error.log
else
# Use unzip for Windows
unzip -q "$FILE" -d "$TMP_DIR" 2> unzip_error.log
extract_exit_code=$?
rm "$FILE" # clean up the downloaded tarball # Check for unzip errors
if [ $extract_exit_code -ne 0 ]; then
echo "Error: Failed to extract $FILE. See details below:"
cat unzip_error.log
rm unzip_error.log
exit 1
fi
rm unzip_error.log
fi
set -e # Re-enable immediate exit on error
rm "$FILE" # clean up the downloaded archive
# Make binary executable # Make binary executable
chmod +x "$TMP_DIR/goose" if [ "$OS" = "windows" ]; then
chmod +x "$TMP_DIR/goose.exe"
else
chmod +x "$TMP_DIR/goose"
fi
# --- 5) Install to $GOOSE_BIN_DIR --- # --- 5) Install to $GOOSE_BIN_DIR ---
if [ ! -d "$GOOSE_BIN_DIR" ]; then if [ ! -d "$GOOSE_BIN_DIR" ]; then
@@ -126,13 +162,25 @@ if [ ! -d "$GOOSE_BIN_DIR" ]; then
fi fi
echo "Moving goose to $GOOSE_BIN_DIR/$OUT_FILE" echo "Moving goose to $GOOSE_BIN_DIR/$OUT_FILE"
mv "$TMP_DIR/goose" "$GOOSE_BIN_DIR/$OUT_FILE" if [ "$OS" = "windows" ]; then
mv "$TMP_DIR/goose.exe" "$GOOSE_BIN_DIR/$OUT_FILE"
else
mv "$TMP_DIR/goose" "$GOOSE_BIN_DIR/$OUT_FILE"
fi
# Also move temporal-service if it exists (for scheduling functionality) # Also move temporal-service if it exists (for scheduling functionality)
if [ -f "$TMP_DIR/temporal-service" ]; then if [ "$OS" = "windows" ]; then
if [ -f "$TMP_DIR/temporal-service.exe" ]; then
echo "Moving temporal-service to $GOOSE_BIN_DIR/temporal-service.exe"
mv "$TMP_DIR/temporal-service.exe" "$GOOSE_BIN_DIR/temporal-service.exe"
chmod +x "$GOOSE_BIN_DIR/temporal-service.exe"
fi
else
if [ -f "$TMP_DIR/temporal-service" ]; then
echo "Moving temporal-service to $GOOSE_BIN_DIR/temporal-service" echo "Moving temporal-service to $GOOSE_BIN_DIR/temporal-service"
mv "$TMP_DIR/temporal-service" "$GOOSE_BIN_DIR/temporal-service" mv "$TMP_DIR/temporal-service" "$GOOSE_BIN_DIR/temporal-service"
chmod +x "$GOOSE_BIN_DIR/temporal-service" chmod +x "$GOOSE_BIN_DIR/temporal-service"
fi
fi fi
# skip configuration for non-interactive installs e.g. automation, docker # skip configuration for non-interactive installs e.g. automation, docker