chore: use hermit to install node, rust and protoc (#2766)

This commit is contained in:
Lifei Zhou
2025-06-04 09:45:43 +10:00
committed by GitHub
parent 5574c20ff2
commit d1f9d4a31e
36 changed files with 170 additions and 82 deletions

View File

@@ -20,6 +20,10 @@ on:
type: string
required: false
default: '["x86_64","aarch64"]'
ref:
type: string
required: false
default: 'refs/heads/main'
name: "Reusable workflow to build CLI"
@@ -41,6 +45,9 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # pin@v4
with:
ref: ${{ inputs.ref }}
fetch-depth: 0
- name: Update version in Cargo.toml
if: ${{ inputs.version != '' }}
@@ -48,14 +55,8 @@ jobs:
sed -i.bak 's/^version = ".*"/version = "'${{ inputs.version }}'"/' Cargo.toml
rm -f Cargo.toml.bak
- name: Setup Rust
uses: dtolnay/rust-toolchain@38b70195107dddab2c7bbd522bcf763bac00963b # pin@stable
with:
toolchain: stable
target: ${{ matrix.architecture }}-${{ matrix.target-suffix }}
- name: Install cross
run: 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
- name: Build CLI
env:
@@ -64,12 +65,7 @@ jobs:
RUST_BACKTRACE: 1
CROSS_VERBOSE: 1
run: |
# Install protoc if on macOS
if [ "${{ matrix.os }}" = "macos-latest" ]; then
brew install protobuf
export PROTOC=$(which protoc)
fi
source ./bin/activate-hermit
export TARGET="${{ matrix.architecture }}-${{ matrix.target-suffix }}"
rustup target add "${TARGET}"
echo "Building for target: ${TARGET}"

View File

@@ -85,20 +85,16 @@ jobs:
# Update version in Cargo.toml
sed -i.bak 's/^version = ".*"/version = "'${{ inputs.version }}'"/' Cargo.toml
rm -f Cargo.toml.bak
# Update version in package.json
# Update version in package.json
source ./bin/activate-hermit
cd ui/desktop
npm version ${{ inputs.version }} --no-git-tag-version --allow-same-version
- name: Setup Rust
uses: dtolnay/rust-toolchain@38b70195107dddab2c7bbd522bcf763bac00963b # pin@stable
with:
toolchain: stable
targets: x86_64-apple-darwin
# Pre-build cleanup to ensure enough disk space
- name: Pre-build cleanup
run: |
source ./bin/activate-hermit
echo "Performing pre-build cleanup..."
# Clean npm cache
npm cache clean --force || true
@@ -137,7 +133,7 @@ jobs:
# Build specifically for Intel architecture
- name: Build goosed for Intel
run: cargo build --release -p goose-server --target x86_64-apple-darwin
run: source ./bin/activate-hermit && cargo build --release -p goose-server --target x86_64-apple-darwin
# Post-build cleanup to free space
- name: Post-build cleanup
@@ -164,13 +160,8 @@ jobs:
CERTIFICATE_OSX_APPLICATION: ${{ secrets.CERTIFICATE_OSX_APPLICATION }}
CERTIFICATE_PASSWORD: ${{ secrets.CERTIFICATE_PASSWORD }}
- name: Set up Node.js
uses: actions/setup-node@7c12f8017d5436eb855f1ed4399f037a36fbd9e8 # pin@v2
with:
node-version: 'lts/*'
- name: Install dependencies
run: npm ci
run: source ../../bin/activate-hermit && npm ci
working-directory: ui/desktop
# Configure Electron builder for Intel architecture
@@ -187,6 +178,7 @@ jobs:
- name: Make Unsigned App
if: ${{ !inputs.signing }}
run: |
source ../../bin/activate-hermit
attempt=0
max_attempts=2
until [ $attempt -ge $max_attempts ]; do
@@ -204,6 +196,7 @@ jobs:
- name: Make Signed App
if: ${{ inputs.signing }}
run: |
source ../../bin/activate-hermit
attempt=0
max_attempts=2
until [ $attempt -ge $max_attempts ]; do

View File

@@ -135,6 +135,7 @@ jobs:
sed -i.bak "s/^version = \".*\"/version = \"${VERSION}\"/" Cargo.toml
rm -f Cargo.toml.bak
source ./bin/activate-hermit
# Update version in package.json
cd ui/desktop
npm version "${VERSION}" --no-git-tag-version --allow-same-version
@@ -142,6 +143,7 @@ jobs:
# Pre-build cleanup to ensure enough disk space
- name: Pre-build cleanup
run: |
source ./bin/activate-hermit
echo "Performing pre-build cleanup..."
# Clean npm cache
npm cache clean --force || true
@@ -154,16 +156,6 @@ jobs:
# Check disk space after cleanup
df -h
- name: Install protobuf
run: |
brew install protobuf
echo "PROTOC=$(which protoc)" >> $GITHUB_ENV
- name: Setup Rust
uses: dtolnay/rust-toolchain@38b70195107dddab2c7bbd522bcf763bac00963b # pin@stable
with:
toolchain: stable
- name: Cache Cargo registry
uses: actions/cache@2f8e54208210a422b2efd51efaa6bd6d7ca8920f # pin@v3
with:
@@ -190,7 +182,7 @@ jobs:
# Build the project
- name: Build goosed
run: cargo build --release -p goose-server
run: source ./bin/activate-hermit && cargo build --release -p goose-server
# Post-build cleanup to free space
- name: Post-build cleanup
@@ -216,13 +208,8 @@ jobs:
CERTIFICATE_OSX_APPLICATION: ${{ secrets.CERTIFICATE_OSX_APPLICATION }}
CERTIFICATE_PASSWORD: ${{ secrets.CERTIFICATE_PASSWORD }}
- name: Set up Node.js
uses: actions/setup-node@7c12f8017d5436eb855f1ed4399f037a36fbd9e8 # pin@v2
with:
node-version: 'lts/*'
- name: Install dependencies
run: npm ci
run: source ../../bin/activate-hermit && npm ci
working-directory: ui/desktop
# Check disk space before bundling
@@ -232,6 +219,7 @@ jobs:
- name: Make Unsigned App
if: ${{ !inputs.signing }}
run: |
source ../../bin/activate-hermit
attempt=0
max_attempts=2
until [ $attempt -ge $max_attempts ]; do
@@ -253,6 +241,7 @@ jobs:
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: |
attempt=0
max_attempts=2
until [ $attempt -ge $max_attempts ]; do

View File

@@ -17,13 +17,8 @@ jobs:
- name: Checkout Code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # pin@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@38b70195107dddab2c7bbd522bcf763bac00963b # pin@stable
with:
toolchain: stable
- name: Run cargo fmt
run: cargo fmt --check
run: source ./bin/activate-hermit && cargo fmt --check
rust-build-and-test:
name: Build and Test Rust Project
@@ -57,12 +52,7 @@ jobs:
- name: Install Dependencies
run: |
sudo apt update -y
sudo apt install -y libdbus-1-dev gnome-keyring libxcb1-dev protobuf-compiler
- name: Setup Rust
uses: dtolnay/rust-toolchain@38b70195107dddab2c7bbd522bcf763bac00963b # pin@stable
with:
toolchain: stable
sudo apt install -y libdbus-1-dev gnome-keyring libxcb1-dev
- name: Cache Cargo Registry
uses: actions/cache@2f8e54208210a422b2efd51efaa6bd6d7ca8920f # pin@v3
@@ -91,7 +81,7 @@ jobs:
- name: Build and Test
run: |
gnome-keyring-daemon --components=secrets --daemonize --unlock <<< 'foobar'
cargo test
source ../bin/activate-hermit && cargo test
working-directory: crates
# Add disk space cleanup before linting
@@ -120,7 +110,7 @@ jobs:
run: df -h
- name: Lint
run: cargo clippy -- -D warnings
run: source ./bin/activate-hermit && cargo clippy -- -D warnings
desktop-lint:
name: Lint Electron Desktop App
@@ -129,17 +119,12 @@ jobs:
- name: Checkout Code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # pin@v4
- name: Set up Node.js
uses: actions/setup-node@7c12f8017d5436eb855f1ed4399f037a36fbd9e8 # pin@v2
with:
node-version: "lts/*"
- name: Install Dependencies
run: npm ci
run: source ../../bin/activate-hermit && npm ci
working-directory: ui/desktop
- name: Run Lint
run: npm run lint:check
run: source ../../bin/activate-hermit && npm run lint:check
working-directory: ui/desktop
# Faster Desktop App build for PRs only

View File

@@ -27,6 +27,7 @@ jobs:
outputs:
continue: ${{ steps.command.outputs.continue || github.event_name == 'workflow_dispatch' }}
pr_number: ${{ steps.command.outputs.issue_number || github.event.inputs.pr_number }}
head_sha: ${{ steps.set_head_sha.outputs.head_sha || github.sha }}
steps:
- if: ${{ github.event_name == 'issue_comment' }}
uses: github/command@v1.3.0
@@ -36,11 +37,23 @@ jobs:
skip_reviews: true
reaction: "eyes"
allowed_contexts: pull_request
- name: Get PR head SHA with gh
id: set_head_sha
run: |
echo "Get PR head SHA with gh"
HEAD_SHA=$(gh pr view "$ISSUE_NUMBER" --json headRefOid -q .headRefOid)
echo "head_sha=$HEAD_SHA" >> $GITHUB_OUTPUT
echo "head_sha=$HEAD_SHA"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_NUMBER: ${{ steps.command.outputs.issue_number }}
build-cli:
needs: [trigger-on-command]
if: ${{ needs.trigger-on-command.outputs.continue == 'true' }}
uses: ./.github/workflows/build-cli.yml
with:
ref: ${{ needs.trigger-on-command.outputs.head_sha }}
pr-comment-cli:
name: PR Comment with CLI builds

3
.gitignore vendored
View File

@@ -24,8 +24,7 @@ target/
./ui/desktop/out
# Hermit
/.hermit/
/bin/
.hermit/
debug_*.txt

View File

@@ -1,11 +1,4 @@
# Configuration for cross-compiling using cross
[build.env]
passthrough = [
"PROTOC",
"RUST_LOG",
"RUST_BACKTRACE"
]
[target.aarch64-unknown-linux-gnu]
xargo = false
pre-build = [
@@ -51,7 +44,6 @@ pre-build = [
protoc --version
"""
]
env = { "PROTOC" = "/usr/bin/protoc", "PATH" = "/usr/local/bin:${PATH}" }
[target.x86_64-pc-windows-gnu]
image = "dockcross/windows-static-x64:latest"

1
bin/.node-22.9.0.pkg Symbolic link
View File

@@ -0,0 +1 @@
hermit

1
bin/.protoc-31.1.pkg Symbolic link
View File

@@ -0,0 +1 @@
hermit

1
bin/.rustup-1.25.2.pkg Symbolic link
View File

@@ -0,0 +1 @@
hermit

7
bin/README.hermit.md Normal file
View File

@@ -0,0 +1,7 @@
# Hermit environment
This is a [Hermit](https://github.com/cashapp/hermit) bin directory.
The symlinks in this directory are managed by Hermit and will automatically
download and install Hermit itself as well as packages. These packages are
local to this environment.

21
bin/activate-hermit Executable file
View File

@@ -0,0 +1,21 @@
#!/bin/bash
# This file must be used with "source bin/activate-hermit" from bash or zsh.
# You cannot run it directly
#
# THIS FILE IS GENERATED; DO NOT MODIFY
if [ "${BASH_SOURCE-}" = "$0" ]; then
echo "You must source this script: \$ source $0" >&2
exit 33
fi
BIN_DIR="$(dirname "${BASH_SOURCE[0]:-${(%):-%x}}")"
if "${BIN_DIR}/hermit" noop > /dev/null; then
eval "$("${BIN_DIR}/hermit" activate "${BIN_DIR}/..")"
if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ]; then
hash -r 2>/dev/null
fi
echo "Hermit environment $("${HERMIT_ENV}"/bin/hermit env HERMIT_ENV) activated"
fi

24
bin/activate-hermit.fish Executable file
View File

@@ -0,0 +1,24 @@
#!/usr/bin/env fish
# This file must be sourced with "source bin/activate-hermit.fish" from Fish shell.
# You cannot run it directly.
#
# THIS FILE IS GENERATED; DO NOT MODIFY
if status is-interactive
set BIN_DIR (dirname (status --current-filename))
if "$BIN_DIR/hermit" noop > /dev/null
# Source the activation script generated by Hermit
"$BIN_DIR/hermit" activate "$BIN_DIR/.." | source
# Clear the command cache if applicable
functions -c > /dev/null 2>&1
# Display activation message
echo "Hermit environment $($HERMIT_ENV/bin/hermit env HERMIT_ENV) activated"
end
else
echo "You must source this script: source $argv[0]" >&2
exit 33
end

1
bin/cargo Symbolic link
View File

@@ -0,0 +1 @@
.rustup-1.25.2.pkg

1
bin/cargo-clippy Symbolic link
View File

@@ -0,0 +1 @@
.rustup-1.25.2.pkg

1
bin/cargo-fmt Symbolic link
View File

@@ -0,0 +1 @@
.rustup-1.25.2.pkg

1
bin/cargo-miri Symbolic link
View File

@@ -0,0 +1 @@
.rustup-1.25.2.pkg

1
bin/clippy-driver Symbolic link
View File

@@ -0,0 +1 @@
.rustup-1.25.2.pkg

1
bin/corepack Symbolic link
View File

@@ -0,0 +1 @@
.node-22.9.0.pkg

43
bin/hermit Executable file
View File

@@ -0,0 +1,43 @@
#!/bin/bash
#
# THIS FILE IS GENERATED; DO NOT MODIFY
set -eo pipefail
export HERMIT_USER_HOME=~
if [ -z "${HERMIT_STATE_DIR}" ]; then
case "$(uname -s)" in
Darwin)
export HERMIT_STATE_DIR="${HERMIT_USER_HOME}/Library/Caches/hermit"
;;
Linux)
export HERMIT_STATE_DIR="${XDG_CACHE_HOME:-${HERMIT_USER_HOME}/.cache}/hermit"
;;
esac
fi
export HERMIT_DIST_URL="${HERMIT_DIST_URL:-https://github.com/cashapp/hermit/releases/download/stable}"
HERMIT_CHANNEL="$(basename "${HERMIT_DIST_URL}")"
export HERMIT_CHANNEL
export HERMIT_EXE=${HERMIT_EXE:-${HERMIT_STATE_DIR}/pkg/hermit@${HERMIT_CHANNEL}/hermit}
if [ ! -x "${HERMIT_EXE}" ]; then
echo "Bootstrapping ${HERMIT_EXE} from ${HERMIT_DIST_URL}" 1>&2
INSTALL_SCRIPT="$(mktemp)"
# This value must match that of the install script
INSTALL_SCRIPT_SHA256="09ed936378857886fd4a7a4878c0f0c7e3d839883f39ca8b4f2f242e3126e1c6"
if [ "${INSTALL_SCRIPT_SHA256}" = "BYPASS" ]; then
curl -fsSL "${HERMIT_DIST_URL}/install.sh" -o "${INSTALL_SCRIPT}"
else
# Install script is versioned by its sha256sum value
curl -fsSL "${HERMIT_DIST_URL}/install-${INSTALL_SCRIPT_SHA256}.sh" -o "${INSTALL_SCRIPT}"
# Verify install script's sha256sum
openssl dgst -sha256 "${INSTALL_SCRIPT}" | \
awk -v EXPECTED="$INSTALL_SCRIPT_SHA256" \
'$2!=EXPECTED {print "Install script sha256 " $2 " does not match " EXPECTED; exit 1}'
fi
/bin/bash "${INSTALL_SCRIPT}" 1>&2
fi
exec "${HERMIT_EXE}" --level=fatal exec "$0" -- "$@"

4
bin/hermit.hcl Normal file
View File

@@ -0,0 +1,4 @@
manage-git = false
github-token-auth {
}

1
bin/node Symbolic link
View File

@@ -0,0 +1 @@
.node-22.9.0.pkg

1
bin/npm Symbolic link
View File

@@ -0,0 +1 @@
.node-22.9.0.pkg

1
bin/npx Symbolic link
View File

@@ -0,0 +1 @@
.node-22.9.0.pkg

1
bin/protoc Symbolic link
View File

@@ -0,0 +1 @@
.protoc-31.1.pkg

1
bin/rls Symbolic link
View File

@@ -0,0 +1 @@
.rustup-1.25.2.pkg

1
bin/rust-analyzer Symbolic link
View File

@@ -0,0 +1 @@
.rustup-1.25.2.pkg

1
bin/rust-gdb Symbolic link
View File

@@ -0,0 +1 @@
.rustup-1.25.2.pkg

1
bin/rust-gdbgui Symbolic link
View File

@@ -0,0 +1 @@
.rustup-1.25.2.pkg

1
bin/rust-lldb Symbolic link
View File

@@ -0,0 +1 @@
.rustup-1.25.2.pkg

1
bin/rustc Symbolic link
View File

@@ -0,0 +1 @@
.rustup-1.25.2.pkg

1
bin/rustdoc Symbolic link
View File

@@ -0,0 +1 @@
.rustup-1.25.2.pkg

1
bin/rustfmt Symbolic link
View File

@@ -0,0 +1 @@
.rustup-1.25.2.pkg

1
bin/rustup Symbolic link
View File

@@ -0,0 +1 @@
.rustup-1.25.2.pkg

View File

@@ -28,7 +28,7 @@ fn default_version() -> String {
///
/// # Example
///
/// ```
///
/// use goose::recipe::Recipe;
///
/// // Using the builder pattern
@@ -52,7 +52,7 @@ fn default_version() -> String {
/// author: None,
/// parameters: None,
/// };
/// ```
///
#[derive(Serialize, Deserialize, Debug)]
pub struct Recipe {
// Required fields
@@ -166,7 +166,7 @@ impl Recipe {
///
/// # Example
///
/// ```
///
/// use goose::recipe::Recipe;
///
/// let recipe = Recipe::builder()
@@ -175,7 +175,7 @@ impl Recipe {
/// .instructions("Act as a helpful assistant")
/// .build()
/// .expect("Failed to build Recipe: missing required fields");
/// ```
///
pub fn builder() -> RecipeBuilder {
RecipeBuilder {
version: default_version(),

View File

@@ -29,7 +29,7 @@ docker pull arm64v8/ubuntu
2. Run the container
pwd is the directory which contains the binary built in the previous step on your host machine
```sh
docker run -v $(pwd):/app -it arm64v8/ubuntu /bin/bash
docker run --rm -v "$(pwd)":/app -it --platform linux/arm64 arm64v8/ubuntu /bin/bash
```
3. Install dependencies in the container and set up api testing environment
@@ -63,7 +63,7 @@ docker pull --platform linux/amd64 debian:latest
2. Run the container
pwd is the directory contains the binary built in the previous step on your host machine
```sh
docker run --platform linux/amd64 -it -v "$(pwd)":/app debian:latest /bin/bash
docker run --rm -v "$(pwd)":/app -it --platform linux/amd64 ubuntu:latest /bin/bash
```
3. Install dependencies in the container and set up api testing environment