Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/toolchain.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Shared CI/agent toolchain pins for NetScript.
#
# Keep these aligned with package scaffold constants and templates. OpenHands
# PR-comment runs hydrate this file from the workflow ref, so fixes here affect
# old PR branches as soon as the workflow is merged to main.
NETSCRIPT_DENO_VERSION=v2.7.11
NETSCRIPT_DOTNET_VERSION=10.0.x
NETSCRIPT_DOTNET_CHANNEL=10.0
NETSCRIPT_ASPIRE_CLI_VERSION=13.2.2
54 changes: 33 additions & 21 deletions .github/workflows/copilot-setup-steps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,22 @@
# audit-fix passes (deno publish --dry-run, deno doc --lint, deno task check,
# deno task e2e:cli) without a local agent.
#
# Toolchain pinned to this repo's reality:
# - Deno 2.x (deno.json uses unstable: kv, temporal, tsgo, worker-options, raw-imports)
# - .NET SDK 10.x (CLI scaffold AppHost/ServiceDefaults target net10.0)
# - Aspire CLI via the official install script, pinned to a release + script hash
# (NOT `dotnet workload install aspire`, which was removed after Aspire 8)
# - Docker (pre-installed on ubuntu-latest; AppHost resources need the engine)
# Toolchain pinned to this repo's reality in .github/toolchain.env:
# - Deno 2.7.x
# - .NET SDK 10.x (CLI scaffold AppHost/ServiceDefaults target net10.0)
# - Aspire CLI 13.2.x (matches scaffold Aspire SDK/package constants)
# - Docker latest stable (AppHost resources need the engine)
name: 'Copilot Setup Steps'

on:
workflow_dispatch:
push:
paths:
- .github/toolchain.env
- .github/workflows/copilot-setup-steps.yml
pull_request:
paths:
- .github/toolchain.env
- .github/workflows/copilot-setup-steps.yml

jobs:
Expand All @@ -35,47 +36,58 @@ jobs:
- name: Checkout code
uses: actions/checkout@v6

- name: Load NetScript toolchain
id: toolchain
shell: bash
run: |
set -euo pipefail
source .github/toolchain.env
echo "deno-version=${NETSCRIPT_DENO_VERSION}" >> "$GITHUB_OUTPUT"
echo "dotnet-version=${NETSCRIPT_DOTNET_VERSION}" >> "$GITHUB_OUTPUT"
echo "aspire-version=${NETSCRIPT_ASPIRE_CLI_VERSION}" >> "$GITHUB_OUTPUT"
grep -F "ASPIRE_SDK: '${NETSCRIPT_ASPIRE_CLI_VERSION}'" \
packages/cli/src/kernel/constants/scaffold/scaffold-versions.ts

# --- Deno (primary toolchain) ---
- name: Setup Deno
uses: denoland/setup-deno@v2
with:
deno-version: v2.x
deno-version: ${{ steps.toolchain.outputs.deno-version }}
cache-hash: ${{ hashFiles('**/deno.json') }}

# --- .NET SDK 10 (Aspire AppHost / ServiceDefaults target net10.0) ---
- name: Setup .NET SDK
uses: actions/setup-dotnet@v5
with:
dotnet-version: '10.0.x'
dotnet-version: ${{ steps.toolchain.outputs.dotnet-version }}

# --- Aspire CLI (standalone install script; adds $HOME/.aspire/bin to PATH) ---
- name: Install Aspire CLI
run: |
set -euo pipefail
aspire_version="13.4.2"
# Commit d7d0b6759ce4b936c76bc4775814d27db560dd6d is the target
# of the v13.4.2 release tag in dotnet/aspire.
# To verify/update: inspect https://github.com/dotnet/aspire/releases/tag/v13.4.2.
installer_url="https://raw.githubusercontent.com/dotnet/aspire/d7d0b6759ce4b936c76bc4775814d27db560dd6d/eng/scripts/get-aspire-cli.sh"
installer_sha256="df1247d87f6e5ca83e71abf55f78bca1bd9a421a3f2f0fd5481f153fc958632a"
aspire_version="${{ steps.toolchain.outputs.aspire-version }}"
installer_url="https://aspire.dev/install.sh"

@augmentcode augmentcode Bot Jun 10, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.github/workflows/copilot-setup-steps.yml:69: Switching to installer_url="https://aspire.dev/install.sh" without any pin/hash verification means CI is now trusting a mutable remote script, which weakens supply-chain integrity compared to the previous pinned+verified installer.

Severity: high

Other Locations
  • .openhands/setup.sh:50

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

installer="$(mktemp)"
trap 'rm -f "$installer"' EXIT
curl --fail --show-error --silent --location --proto '=https' --tlsv1.2 \
--output "$installer" "$installer_url"
# sha256sum --check expects the hash, two space characters, then the filename.
if ! echo "$installer_sha256 $installer" | sha256sum --check; then
echo "::error::Aspire installer hash verification failed for $installer_url"
exit 1
fi
bash "$installer" --version "$aspire_version" --install-path "$HOME/.aspire/bin" --skip-path
echo "$HOME/.aspire/bin" >> "$GITHUB_PATH"

- name: Verify Aspire CLI
run: |
set -euo pipefail
export PATH="$HOME/.aspire/bin:$PATH"
aspire --version
actual="$(aspire --version)"
echo "$actual"
test "$actual" = "${{ steps.toolchain.outputs.aspire-version }}"

@augmentcode augmentcode Bot Jun 10, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.github/workflows/copilot-setup-steps.yml:83: test "$actual" = "..." assumes aspire --version outputs exactly the raw version string; if the CLI ever includes a prefix/suffix this will fail even when the correct version is installed.

Severity: medium

Other Locations
  • .openhands/setup.sh:65

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.


# --- Docker (AppHost container resources) ---
- name: Setup Docker
uses: docker/setup-docker-action@v5
with:
version: latest

# --- Docker (AppHost container resources; engine is pre-installed) ---
- name: Verify Docker
run: |
docker --version
Expand Down
7 changes: 6 additions & 1 deletion .github/workflows/openhands-agent.yml
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ jobs:
WORKFLOW_REF: ${{ github.sha }}
run: |
mkdir -p /tmp/openhands-runtime
for path in .openhands/setup.sh .openhands/agent_runner.py; do
for path in .openhands/setup.sh .openhands/agent_runner.py .github/toolchain.env; do
target="/tmp/openhands-runtime/$(basename "$path")"
gh api "repos/${GITHUB_REPOSITORY}/contents/${path}?ref=${WORKFLOW_REF}" \
--jq .content | base64 -d > "$target"
Expand Down Expand Up @@ -318,6 +318,11 @@ jobs:
> .llm/tmp/openhands/pr-review-comments.json || true
fi

- name: Setup Docker
uses: docker/setup-docker-action@v5
with:
version: latest

- name: Bootstrap NetScript toolchain
run: bash /tmp/openhands-runtime/setup.sh

Expand Down
56 changes: 48 additions & 8 deletions .openhands/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,71 @@ set -euo pipefail

echo "Bootstrapping NetScript for OpenHands"

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
toolchain_file="${NETSCRIPT_TOOLCHAIN_FILE:-}"
if [ -z "$toolchain_file" ]; then
if [ -f "$script_dir/toolchain.env" ]; then
toolchain_file="$script_dir/toolchain.env"
elif [ -f ".github/toolchain.env" ]; then
toolchain_file=".github/toolchain.env"
fi
fi

if [ -z "$toolchain_file" ] || [ ! -f "$toolchain_file" ]; then
echo "Missing NetScript toolchain file."
exit 1
fi

# shellcheck source=/dev/null
source "$toolchain_file"

: "${NETSCRIPT_DENO_VERSION:?}"
: "${NETSCRIPT_DOTNET_CHANNEL:?}"
: "${NETSCRIPT_ASPIRE_CLI_VERSION:?}"

export DENO_INSTALL="${DENO_INSTALL:-$HOME/.deno}"
export PATH="$DENO_INSTALL/bin:$HOME/.aspire/bin:$HOME/.dotnet:$PATH"

if ! command -v deno >/dev/null 2>&1; then
curl -fsSL https://deno.land/install.sh | sh -s -- -y
fi

if ! command -v dotnet >/dev/null 2>&1; then
curl -fsSL https://dot.net/v1/dotnet-install.sh -o /tmp/dotnet-install.sh
bash /tmp/dotnet-install.sh --channel 10.0 --install-dir "$HOME/.dotnet"
target_deno="${NETSCRIPT_DENO_VERSION#v}"
actual_deno="$(deno --version | awk 'NR==1 {print $2}')"
if [ "$actual_deno" != "$target_deno" ]; then
deno upgrade --version "$target_deno"
fi

if ! command -v aspire >/dev/null 2>&1; then
curl -fsSL https://aspire.dev/install.sh | bash
target_dotnet_major="${NETSCRIPT_DOTNET_CHANNEL%%.*}"
if ! command -v dotnet >/dev/null 2>&1 ||
! dotnet --list-sdks 2>/dev/null | grep -Eq "^${target_dotnet_major}\."; then
curl -fsSL https://dot.net/v1/dotnet-install.sh -o /tmp/dotnet-install.sh
bash /tmp/dotnet-install.sh --channel "$NETSCRIPT_DOTNET_CHANNEL" --install-dir "$HOME/.dotnet"
fi

aspire_installer="$(mktemp)"
trap 'rm -f "$aspire_installer"' EXIT
curl -fsSL https://aspire.dev/install.sh -o "$aspire_installer"
bash "$aspire_installer" \
--version "$NETSCRIPT_ASPIRE_CLI_VERSION" \
--install-path "$HOME/.aspire/bin" \
--skip-path

echo "$DENO_INSTALL/bin" >> "$GITHUB_PATH" 2>/dev/null || true
echo "$HOME/.aspire/bin" >> "$GITHUB_PATH" 2>/dev/null || true
echo "$HOME/.dotnet" >> "$GITHUB_PATH" 2>/dev/null || true

deno --version
dotnet --version
aspire --version || true
docker --version || true
docker compose version || true
dotnet --list-sdks | grep -E "^${target_dotnet_major}\."
actual_aspire="$(aspire --version)"
echo "$actual_aspire"
if [ "$actual_aspire" != "$NETSCRIPT_ASPIRE_CLI_VERSION" ]; then
echo "Aspire CLI version mismatch: expected $NETSCRIPT_ASPIRE_CLI_VERSION, got $actual_aspire"
exit 1
fi
docker --version
docker compose version

deno install || echo "deno install non-fatal during OpenHands setup"
dotnet nuget locals all --list || true
Expand Down
Loading