Skip to content

Commit 1c5e40b

Browse files
committed
Add feature for copilot-cli
1 parent 31f99a0 commit 1c5e40b

File tree

4 files changed

+195
-0
lines changed

4 files changed

+195
-0
lines changed

src/copilot-cli/NOTES.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
3+
## OS Support
4+
5+
This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed.
6+
7+
`bash` is required to execute the `install.sh` script.

src/copilot-cli/README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
2+
# GitHub Copilot CLI (copilot-cli)
3+
4+
Installs the GitHub Copilot CLI. Auto-detects latest version and installs needed dependencies.
5+
6+
## Example Usage
7+
8+
```json
9+
"features": {
10+
"ghcr.io/devcontainers/features/copilot-cli:1": {}
11+
}
12+
```
13+
14+
## Options
15+
16+
| Options Id | Description | Type | Default Value |
17+
|-----|-----|-----|-----|
18+
| version | Select version of the GitHub Copilot CLI, if not latest. | string | latest |
19+
| installDirectlyFromGitHubRelease | - | boolean | true |
20+
21+
22+
23+
## OS Support
24+
25+
This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed.
26+
27+
`bash` is required to execute the `install.sh` script.
28+
29+
30+
---
31+
32+
_Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/copilot-cli/devcontainer-feature.json). Add additional notes to a `NOTES.md`._
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"id": "copilot-cli",
3+
"version": "0.0.367",
4+
"name": "GitHub Copilot CLI",
5+
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/copilot-cli",
6+
"description": "Installs the GitHub Copilot CLI.",
7+
"options": {
8+
"version": {
9+
"type": "string",
10+
"proposals": [
11+
"latest",
12+
"none"
13+
],
14+
"default": "latest",
15+
"description": "Select version of the GitHub Copilot CLI, if not latest."
16+
}
17+
},
18+
"customizations": {
19+
"vscode": {
20+
"settings": {
21+
"github.copilot.chat.codeGeneration.instructions": [
22+
{
23+
"text": "This dev container includes the GitHub Copilot CLI (`copilot`), which is pre-installed and available on the `PATH`."
24+
}
25+
]
26+
}
27+
}
28+
},
29+
"installsAfter": [
30+
"ghcr.io/devcontainers/features/common-utils"
31+
]
32+
}
33+

src/copilot-cli/install.sh

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#!/usr/bin/env bash
2+
#-------------------------------------------------------------------------------------------------------------
3+
# Copyright (c) Microsoft Corporation. All rights reserved.
4+
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
5+
#-------------------------------------------------------------------------------------------------------------
6+
#
7+
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/github.md
8+
# Maintainer: The VS Code and Codespaces Teams
9+
10+
CLI_VERSION=${VERSION:-"latest"}
11+
12+
set -e
13+
14+
if [ "$(id -u)" -ne 0 ]; then
15+
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
16+
exit 1
17+
fi
18+
19+
# Figure out correct version of a three part version number is not passed
20+
find_version_from_git_tags() {
21+
local variable_name=$1
22+
local requested_version=${!variable_name}
23+
if [ "${requested_version}" = "none" ]; then return; fi
24+
local repository=$2
25+
local prefix=${3:-"tags/v"}
26+
local separator=${4:-"."}
27+
local last_part_optional=${5:-"false"}
28+
if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then
29+
local escaped_separator=${separator//./\\.}
30+
local last_part
31+
if [ "${last_part_optional}" = "true" ]; then
32+
last_part="(${escaped_separator}[0-9]+)?"
33+
else
34+
last_part="${escaped_separator}[0-9]+"
35+
fi
36+
local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$"
37+
local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)"
38+
if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then
39+
declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)"
40+
else
41+
set +e
42+
declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")"
43+
set -e
44+
fi
45+
fi
46+
if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then
47+
echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2
48+
exit 1
49+
fi
50+
echo "${variable_name}=${!variable_name}"
51+
}
52+
53+
# Use semver logic to decrement a version number then look for the closest match
54+
find_prev_version_from_git_tags() {
55+
local variable_name=$1
56+
local current_version=${!variable_name}
57+
local repository=$2
58+
# Normally a "v" is used before the version number, but support alternate cases
59+
local prefix=${3:-"tags/v"}
60+
# Some repositories use "_" instead of "." for version number part separation, support that
61+
local separator=${4:-"."}
62+
# Some tools release versions that omit the last digit (e.g. go)
63+
local last_part_optional=${5:-"false"}
64+
# Some repositories may have tags that include a suffix (e.g. actions/node-versions)
65+
local version_suffix_regex=$6
66+
# Try one break fix version number less if we get a failure. Use "set +e" since "set -e" can cause failures in valid scenarios.
67+
set +e
68+
major="$(echo "${current_version}" | grep -oE '^[0-9]+' || echo '')"
69+
minor="$(echo "${current_version}" | grep -oP '^[0-9]+\.\K[0-9]+' || echo '')"
70+
breakfix="$(echo "${current_version}" | grep -oP '^[0-9]+\.[0-9]+\.\K[0-9]+' 2>/dev/null || echo '')"
71+
72+
if [ "${minor}" = "0" ] && [ "${breakfix}" = "0" ]; then
73+
((major=major-1))
74+
declare -g ${variable_name}="${major}"
75+
# Look for latest version from previous major release
76+
find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${last_part_optional}"
77+
# Handle situations like Go's odd version pattern where "0" releases omit the last part
78+
elif [ "${breakfix}" = "" ] || [ "${breakfix}" = "0" ]; then
79+
((minor=minor-1))
80+
declare -g ${variable_name}="${major}.${minor}"
81+
# Look for latest version from previous minor release
82+
find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${last_part_optional}"
83+
else
84+
((breakfix=breakfix-1))
85+
if [ "${breakfix}" = "0" ] && [ "${last_part_optional}" = "true" ]; then
86+
declare -g ${variable_name}="${major}.${minor}"
87+
else
88+
declare -g ${variable_name}="${major}.${minor}.${breakfix}"
89+
fi
90+
fi
91+
set -e
92+
}
93+
94+
install_using_github() {
95+
check_packages wget
96+
arch=$(dpkg --print-architecture)
97+
98+
find_version_from_git_tags CLI_VERSION https://github.com/github/copilot-cli
99+
cli_filename="copilot_linux_${arch}.tar.gz"
100+
101+
mkdir -p /tmp/copilotcli
102+
pushd /tmp/copilotcli
103+
wget -q --show-progress --progress=dot:giga https://github.com/github/copilot-cli/releases/download/v${CLI_VERSION}/${cli_filename}
104+
exit_code=$?
105+
set -e
106+
if [ "$exit_code" != "0" ]; then
107+
# Handle situation where git tags are ahead of what was is available to actually download
108+
echo "(!) copilot-cli version ${CLI_VERSION} failed to download. Attempting to fall back one version to retry..."
109+
find_prev_version_from_git_tags CLI_VERSION https://github.com/github/copilot-cli
110+
wget -q --show-progress --progress=dot:giga https://github.com/github/copilot-cli/releases/download/v${CLI_VERSION}/${cli_filename}
111+
fi
112+
113+
tar -xzf /tmp/copilotcli/${cli_filename}
114+
mv copilot /usr/local/bin/copilot
115+
popd
116+
rm -rf /tmp/copilotcli
117+
}
118+
119+
# Install the Copilot CLI
120+
echo "Downloading Copilot CLI..."
121+
122+
install_using_github
123+

0 commit comments

Comments
 (0)