Skip to content
Open
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
2 changes: 1 addition & 1 deletion .agents/skills/launch/scripts/launch.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function Exit-Usage([string]$message) {
}

function Get-UsableNode([string]$repoPath) {
$command = Get-Command node -CommandType Application -ErrorAction SilentlyContinue
$command = Get-Command node -CommandType Application -ErrorAction SilentlyContinue | Select-Object -First 1
$nvmrcPath = Join-Path $repoPath '.nvmrc'
$requiredVersion = if (Test-Path -LiteralPath $nvmrcPath -PathType Leaf) {
(Get-Content -LiteralPath $nvmrcPath -Raw).Trim().TrimStart('v')
Expand Down
53 changes: 49 additions & 4 deletions .github/workflows/pr-linux-cli-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,22 @@ on:
rustup_toolchain:
type: string
required: true
working_directory:
type: string
required: false
default: cli
format:
type: boolean
required: false
default: false
locked:
type: boolean
required: false
default: false
all_targets:
type: boolean
required: false
default: false

jobs:
linux-cli-test:
Expand All @@ -33,16 +49,45 @@ jobs:
rustup update $RUSTUP_TOOLCHAIN
rustup component add clippy

- name: Install Rust formatting component
if: ${{ inputs.format }}
run: rustup component add rustfmt

- name: Check Rust versions
run: |
set -e
rustc --version
cargo --version

- name: Check formatting
if: ${{ inputs.format }}
run: cargo fmt --check
working-directory: ${{ inputs.working_directory }}

- name: Clippy lint
run: cargo clippy -- -D warnings
working-directory: cli
run: |
set -e
args=()
if [[ "$CARGO_ALL_TARGETS" == "true" ]]; then
args+=(--all-targets)
fi
if [[ "$CARGO_LOCKED" == "true" ]]; then
args+=(--locked)
fi
cargo clippy "${args[@]}" -- -D warnings
working-directory: ${{ inputs.working_directory }}
env:
CARGO_ALL_TARGETS: ${{ inputs.all_targets }}
CARGO_LOCKED: ${{ inputs.locked }}

- name: 🧪 Run unit tests
run: cargo test
working-directory: cli
run: |
set -e
args=()
if [[ "$CARGO_LOCKED" == "true" ]]; then
args+=(--locked)
fi
cargo test "${args[@]}"
working-directory: ${{ inputs.working_directory }}
env:
CARGO_LOCKED: ${{ inputs.locked }}
20 changes: 18 additions & 2 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,21 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Check Markdown editor manifests
- name: Check Markdown editor manifests and clipboard
run: |
npm run markdown-editor-package-json-check
npm --prefix extensions/markdown-language-features run test-markdown-editor-package-json
npm --prefix extensions/markdown-language-features run test-markdown-editor-clipboard

- name: Compile & Hygiene
run: npm exec -- npm-run-all2 -lp core-ci hygiene eslint valid-layers-check define-class-fields-check vscode-dts-compile-check tsec-compile-check test-build-scripts
run: npm exec -- npm-run-all2 -lp core-ci hygiene valid-layers-check define-class-fields-check vscode-dts-compile-check tsec-compile-check test-build-scripts
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

# Avoid overlapping ESLint's worker memory with the parallel compilation checks.
- name: ESLint
run: npm run eslint

- name: Check Codex protocol client is in sync
run: |
git fetch --no-tags --depth=1 origin "$CODEX_SYNC_BASE" || true
Expand All @@ -117,6 +122,17 @@ jobs:
job_name: CLI
rustup_toolchain: 1.88

linux-copilot-shim-tests:
name: Linux Copilot Shim
uses: ./.github/workflows/pr-linux-cli-test.yml
with:
job_name: Copilot-Shim
rustup_toolchain: 1.88
working_directory: copilot_shim
format: true
locked: true
all_targets: true

linux-electron-unit-tests:
name: Linux
uses: ./.github/workflows/pr-linux-test.yml
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ vscode.db
/.profile-oss
/cli/target
/cli/openssl
/copilot_shim/target
product.overrides.json
*.snap.actual
*.tsbuildinfo
Expand Down
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@
"emmet.excludeLanguages": [],
"gulp.autoDetect": "off",
"rust-analyzer.linkedProjects": [
"cli/Cargo.toml"
"cli/Cargo.toml",
"copilot_shim/Cargo.toml"
],
"conventionalCommits.scopes": [
"tree",
Expand Down
28 changes: 28 additions & 0 deletions build/azure-pipelines/alpine/product-build-alpine-cli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ jobs:
sbomBuildDropPath: $(Build.ArtifactStagingDirectory)/cli
sbomPackageName: "VS Code Alpine $(VSCODE_ARCH) CLI"
sbomPackageVersion: $(Build.SourceVersion)
# The Alpine job adds the Copilot shim to the server builds.
- output: pipelineArtifact
targetPath: $(Build.ArtifactStagingDirectory)/unsigned_copilot_shim_alpine_$(VSCODE_ARCH).tar.gz
artifactName: unsigned_copilot_shim_alpine_$(VSCODE_ARCH)
displayName: Publish unsigned Copilot shim
sbomEnabled: false
steps:
- template: ../common/checkout.yml@self

Expand Down Expand Up @@ -130,3 +136,25 @@ jobs:
OPENSSL_STATIC: "1"
SYSROOT_ARCH: arm64
IS_MUSL: "1"

- ${{ if eq(parameters.VSCODE_ARCH, 'x64') }}:
- template: ../copilot-shim/copilot-shim-compile.yml@self
parameters:
COPILOT_SHIM_TARGET: x86_64-unknown-linux-musl
COPILOT_SHIM_ARTIFACT: unsigned_copilot_shim_alpine_x64
COPILOT_SHIM_CHECK_ONLY: ${{ parameters.VSCODE_CHECK_ONLY }}
COPILOT_SHIM_ENV:
CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER: musl-gcc
CC_x86_64_unknown_linux_musl: musl-gcc
CXX_x86_64_unknown_linux_musl: musl-g++

- ${{ if eq(parameters.VSCODE_ARCH, 'arm64') }}:
- template: ../copilot-shim/copilot-shim-compile.yml@self
parameters:
COPILOT_SHIM_TARGET: aarch64-unknown-linux-musl
COPILOT_SHIM_ARTIFACT: unsigned_copilot_shim_alpine_arm64
COPILOT_SHIM_CHECK_ONLY: ${{ parameters.VSCODE_CHECK_ONLY }}
COPILOT_SHIM_ENV:
GITHUB_TOKEN: "$(github-token-code-oss)"
SYSROOT_ARCH: arm64
IS_MUSL: "1"
19 changes: 19 additions & 0 deletions build/azure-pipelines/alpine/product-build-alpine.yml
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,11 @@ jobs:
- script: node build/azure-pipelines/distro/mixin-quality.ts
displayName: Mixin distro quality

- script: npx deemon --detach --wait -- node build/azure-pipelines/common/waitForArtifacts.ts "--producer=unsigned_copilot_shim_alpine_$(VSCODE_ARCH)=Alpine CLI (${{ upper(parameters.VSCODE_ARCH) }})"
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
displayName: Wait for Copilot shim artifact (background)

- template: ../common/install-builtin-extensions.yml@self

- script: node build/npm/electronTypes.ts
Expand All @@ -229,11 +234,25 @@ jobs:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
displayName: Download Copilot VSIX

- script: npx deemon --attach -- node build/azure-pipelines/common/waitForArtifacts.ts "--producer=unsigned_copilot_shim_alpine_$(VSCODE_ARCH)=Alpine CLI (${{ upper(parameters.VSCODE_ARCH) }})"
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
displayName: Wait for Copilot shim artifact

- task: DownloadPipelineArtifact@2
inputs:
artifact: unsigned_copilot_shim_alpine_$(VSCODE_ARCH)
patterns: "**"
path: $(Build.ArtifactStagingDirectory)/copilot-shim
displayName: Download Copilot shim

- script: |
set -e
TARGET=$([ "$VSCODE_ARCH" == "x64" ] && echo "linux-alpine" || echo "alpine-arm64") # TODO@joaomoreno
npm run gulp vscode-reh-$TARGET-min-ci
(cd .. && mv vscode-reh-$TARGET vscode-server-$TARGET) # TODO@joaomoreno
tar -xzf $(Build.ArtifactStagingDirectory)/copilot-shim/*.tar.gz -C $(Build.ArtifactStagingDirectory)/copilot-shim
install -D -m 755 $(Build.ArtifactStagingDirectory)/copilot-shim/copilot ../vscode-server-$TARGET/bin/copilot-shim/copilot
ARCHIVE_PATH="$(Build.ArtifactStagingDirectory)/out/server/vscode-server-$TARGET.tar.gz"
DIR_PATH="$(realpath ../vscode-server-$TARGET)"
mkdir -p $(dirname $ARCHIVE_PATH)
Expand Down
167 changes: 167 additions & 0 deletions build/azure-pipelines/copilot-shim/copilot-shim-compile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# Builds the native Copilot CLI shim in a VS Code CLI job, after cli-compile.yml has installed Rust and sccache, and
# stages it as <COPILOT_SHIM_ARTIFACT>.zip (Windows, macOS) or .tar.gz (Linux, Alpine). The shim is published
# unsigned; the product build places it in bin/copilot-shim of the client and server builds before signing them.
# The build shares the CLI's sccache directory and cache, because the sccache server that the CLI build started keeps
# serving its own directory for the rest of the job.
parameters:
- name: COPILOT_SHIM_TARGET
type: string
- name: COPILOT_SHIM_ARTIFACT
type: string
- name: COPILOT_SHIM_ENV
type: object
default: {}
- name: COPILOT_SHIM_CHECK_ONLY
type: boolean
default: false

steps:
- ${{ if contains(parameters.COPILOT_SHIM_TARGET, '-linux-') }}:
- script: |
set -e
if [ -n "$SYSROOT_ARCH" ]; then
export VSCODE_SYSROOT_DIR=$(Build.SourcesDirectory)/.build/sysroots
node -e 'import { getVSCodeSysroot } from "../build/linux/debian/install-sysroot.ts"; (async () => { await getVSCodeSysroot(process.env["SYSROOT_ARCH"], process.env["IS_MUSL"] === "1"); })()'
if [ "$SYSROOT_ARCH" = "arm64" ]; then
if [ "$IS_MUSL" = "1" ]; then
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER="$VSCODE_SYSROOT_DIR/output/bin/aarch64-linux-musl-gcc"
export CC_aarch64_unknown_linux_musl="$VSCODE_SYSROOT_DIR/output/bin/aarch64-linux-musl-gcc"
export CXX_aarch64_unknown_linux_musl="$VSCODE_SYSROOT_DIR/output/bin/aarch64-linux-musl-g++"
else
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER="$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc"
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS="-C link-arg=--sysroot=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot"
export CC_aarch64_unknown_linux_gnu="$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc --sysroot=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot"
export PKG_CONFIG_LIBDIR_aarch64_unknown_linux_gnu="$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot/usr/lib/aarch64-linux-gnu/pkgconfig:$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot/usr/share/pkgconfig"
export PKG_CONFIG_SYSROOT_DIR_aarch64_unknown_linux_gnu="$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot"
export OBJDUMP="$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/bin/objdump"
fi
elif [ "$SYSROOT_ARCH" = "amd64" ]; then
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER="$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/bin/x86_64-linux-gnu-gcc"
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS="-C link-arg=--sysroot=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot -C link-arg=-L$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/usr/lib/x86_64-linux-gnu"
export CC_x86_64_unknown_linux_gnu="$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/bin/x86_64-linux-gnu-gcc --sysroot=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot"
export PKG_CONFIG_LIBDIR_x86_64_unknown_linux_gnu="$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/usr/lib/x86_64-linux-gnu/pkgconfig:$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/usr/share/pkgconfig"
export PKG_CONFIG_SYSROOT_DIR_x86_64_unknown_linux_gnu="$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot"
export OBJDUMP="$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/bin/objdump"
elif [ "$SYSROOT_ARCH" = "armhf" ]; then
export CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER="$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-gcc"
export CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_RUSTFLAGS="-C link-arg=--sysroot=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot"
export CC_armv7_unknown_linux_gnueabihf="$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-gcc --sysroot=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot"
export PKG_CONFIG_LIBDIR_armv7_unknown_linux_gnueabihf="$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot/usr/lib/arm-rpi-linux-gnueabihf/pkgconfig:$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot/usr/share/pkgconfig"
export PKG_CONFIG_SYSROOT_DIR_armv7_unknown_linux_gnueabihf="$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot"
export OBJDUMP="$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/bin/objdump"
fi
fi

cargo build --release --locked --target ${{ parameters.COPILOT_SHIM_TARGET }} --bin copilot

if [ "$VERIFY_GLIBC" = "1" ]; then
maximum_glibc_version="2.28"
while IFS= read -r line; do
if [[ "$line" == *"GLIBC_"* ]]; then
version=$(echo "$line" | awk '{print $5}' | tr -d '()')
version=${version#*_}
if [[ $(printf "%s\n%s" "$version" "$maximum_glibc_version" | sort -V | tail -n1) == "$version" ]]; then
maximum_glibc_version=$version
fi
fi
done < <("$OBJDUMP" -T "$PWD/target/${{ parameters.COPILOT_SHIM_TARGET }}/release/copilot")
if [ "$maximum_glibc_version" != "2.28" ]; then
echo "Error: Copilot shim has dependency on GLIBC > 2.28, found $maximum_glibc_version"
exit 1
fi
echo "Copilot shim has no GLIBC dependency newer than 2.28."
fi
displayName: Compile ${{ parameters.COPILOT_SHIM_TARGET }}
workingDirectory: $(Build.SourcesDirectory)/copilot_shim
env:
RUSTC_WRAPPER: sccache
SCCACHE_DIR: $(Pipeline.Workspace)/sccache
${{ each pair in parameters.COPILOT_SHIM_ENV }}:
${{ pair.key }}: ${{ pair.value }}

- ${{ else }}:
- script: cargo build --release --locked --target ${{ parameters.COPILOT_SHIM_TARGET }} --bin copilot
displayName: Compile ${{ parameters.COPILOT_SHIM_TARGET }}
workingDirectory: $(Build.SourcesDirectory)/copilot_shim
env:
RUSTC_WRAPPER: sccache
SCCACHE_DIR: $(Pipeline.Workspace)/sccache
${{ each pair in parameters.COPILOT_SHIM_ENV }}:
${{ pair.key }}: ${{ pair.value }}

- ${{ if not(parameters.COPILOT_SHIM_CHECK_ONLY) }}:
- ${{ if contains(parameters.COPILOT_SHIM_TARGET, '-windows-') }}:
- pwsh: |
$stageDirectory = "$(Build.ArtifactStagingDirectory)/${{ parameters.COPILOT_SHIM_ARTIFACT }}"
New-Item -ItemType Directory -Force -Path $stageDirectory
Copy-Item "$(Build.SourcesDirectory)/copilot_shim/target/${{ parameters.COPILOT_SHIM_TARGET }}/release/copilot.exe" "$stageDirectory/copilot.exe"
$stagedEntries = @(Get-ChildItem -Path $stageDirectory)
if ($stagedEntries.Count -ne 1 -or $stagedEntries[0].Name -ne "copilot.exe") {
throw "Copilot shim staging must contain exactly one root copilot.exe"
}
displayName: Stage Copilot shim

- task: ArchiveFiles@2
displayName: Archive Copilot shim
inputs:
rootFolderOrFile: $(Build.ArtifactStagingDirectory)/${{ parameters.COPILOT_SHIM_ARTIFACT }}/copilot.exe
includeRootFolder: false
archiveType: zip
archiveFile: $(Build.ArtifactStagingDirectory)/${{ parameters.COPILOT_SHIM_ARTIFACT }}.zip

- pwsh: |
Add-Type -AssemblyName System.IO.Compression.FileSystem
$archive = [System.IO.Compression.ZipFile]::OpenRead("$(Build.ArtifactStagingDirectory)/${{ parameters.COPILOT_SHIM_ARTIFACT }}.zip")
try {
$entries = @($archive.Entries)
if ($entries.Count -ne 1 -or $entries[0].FullName -ne "copilot.exe" -or $entries[0].Length -eq 0) {
throw "Copilot shim archive must contain exactly one non-empty root copilot.exe"
}
} finally {
$archive.Dispose()
}
displayName: Validate Copilot shim archive

- ${{ else }}:
- script: |
set -e
stage_directory="$(Build.ArtifactStagingDirectory)/${{ parameters.COPILOT_SHIM_ARTIFACT }}"
mkdir -p "$stage_directory"
install -m 755 "$(Build.SourcesDirectory)/copilot_shim/target/${{ parameters.COPILOT_SHIM_TARGET }}/release/copilot" "$stage_directory/copilot"
test "$(find "$stage_directory" -mindepth 1 -maxdepth 1 | wc -l | tr -d ' ')" = "1"
test -x "$stage_directory/copilot"
displayName: Stage Copilot shim

- task: ArchiveFiles@2
displayName: Archive Copilot shim
inputs:
rootFolderOrFile: $(Build.ArtifactStagingDirectory)/${{ parameters.COPILOT_SHIM_ARTIFACT }}/copilot
includeRootFolder: false
${{ if contains(parameters.COPILOT_SHIM_TARGET, '-darwin') }}:
archiveType: zip
archiveFile: $(Build.ArtifactStagingDirectory)/${{ parameters.COPILOT_SHIM_ARTIFACT }}.zip
${{ else }}:
archiveType: tar
tarCompression: gz
archiveFile: $(Build.ArtifactStagingDirectory)/${{ parameters.COPILOT_SHIM_ARTIFACT }}.tar.gz

- script: |
set -e
validation_directory="$(Build.ArtifactStagingDirectory)/${{ parameters.COPILOT_SHIM_ARTIFACT }}-validation"
rm -rf "$validation_directory"
mkdir -p "$validation_directory"
if [[ "${{ parameters.COPILOT_SHIM_TARGET }}" == *"-darwin" ]]; then
unzip -q "$(Build.ArtifactStagingDirectory)/${{ parameters.COPILOT_SHIM_ARTIFACT }}.zip" -d "$validation_directory"
else
tar -xzf "$(Build.ArtifactStagingDirectory)/${{ parameters.COPILOT_SHIM_ARTIFACT }}.tar.gz" -C "$validation_directory"
fi
test "$(find "$validation_directory" -mindepth 1 -maxdepth 1 | wc -l | tr -d ' ')" = "1"
test -f "$validation_directory/copilot"
test -x "$validation_directory/copilot"
displayName: Validate Copilot shim archive

- script: sccache --show-stats
displayName: Copilot shim sccache stats
condition: succeededOrFailed()
env:
SCCACHE_DIR: $(Pipeline.Workspace)/sccache
Loading