Skip to content

Commit 8bd6ad7

Browse files
CopilotKaniska244
andauthored
fix(copilot-cli): use semver sort for prerelease tag resolution (#1657)
* Initial plan * fix(copilot-cli): use semver sort for prerelease tag resolution * refactor(copilot-cli): extract resolve_prerelease_version function and add test Extract the prerelease tag resolution logic into a standalone resolve_prerelease_version() function that can read from stdin for testing. Add a scenario test that validates version sorting with mock git ls-remote data to prevent regressions. * fix(copilot-cli): make repo_url mandatory in resolve_prerelease_version Remove the stdin/cat fallback and use ${1:?} to error if no URL is provided. Update the test to mock git via PATH instead of piping stdin. * Add tests as per review comments without git ls and separate test for prerelease tag * Further changes in the test and code cleanup --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Kaniska <kaniska244@github.com>
1 parent 0c44deb commit 8bd6ad7

5 files changed

Lines changed: 81 additions & 2 deletions

File tree

src/copilot-cli/devcontainer-feature.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"id": "copilot-cli",
3-
"version": "1.1.2",
3+
"version": "1.1.3",
44
"name": "GitHub Copilot CLI",
55
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/copilot-cli",
66
"description": "Installs the GitHub Copilot CLI.",

src/copilot-cli/install.sh

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ check_packages() {
3131
fi
3232
}
3333

34+
resolve_prerelease_version() {
35+
local repo_versions="${1:?resolve_prerelease_version requires the copilot-cli repo tags as input}"
36+
printf '%s\n' "${repo_versions}" \
37+
| awk '{print $2}' | sed 's|refs/tags/||' \
38+
| grep -E '^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9]+)?$' \
39+
| sort -V | tail -n1
40+
}
41+
3442
download_from_github() {
3543
local release_url=$1
3644
echo "Downloading GitHub Copilot CLI from ${release_url}..."
@@ -63,8 +71,10 @@ install_using_github() {
6371
if [ "${CLI_VERSION}" = "latest" ]; then
6472
download_from_github "https://github.com/github/copilot-cli/releases/latest/download/${cli_filename}"
6573
elif [ "${CLI_VERSION}" = "prerelease" ]; then
66-
prerelease_version="$(git ls-remote --tags https://github.com/github/copilot-cli | tail -1 | awk -F/ '{print $NF}')"
74+
75+
prerelease_version="$(resolve_prerelease_version "$(git ls-remote --tags https://github.com/github/copilot-cli)")"
6776
download_from_github "https://github.com/github/copilot-cli/releases/download/${prerelease_version}/${cli_filename}"
77+
6878
else
6979
# Install specific version
7080
# Add leading v to version if it doesn't start with v
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/usr/bin/env bash
2+
3+
set -e
4+
5+
# Optional: Import test library
6+
source dev-container-features-test-lib
7+
8+
# End-to-end check that the "prerelease" channel actually resolves a tag and
9+
# installs the binary. Regression guard for the inline pipeline in
10+
# src/copilot-cli/install.sh.
11+
12+
check "copilot binary is on PATH" which copilot
13+
check "copilot reports a version" bash -c "copilot -v"
14+
15+
# Auto-update flag file must exist for prerelease channel.
16+
check "auto-update flag created for prerelease" test -f /etc/devcontainer-copilot-cli/auto-update
17+
18+
# Report result
19+
reportResults
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
# Optional: Import test library
6+
source dev-container-features-test-lib
7+
8+
resolve_prerelease_version() {
9+
local repo_versions="${1:?resolve_prerelease_version requires the copilot-cli repo tags as input}"
10+
printf '%s\n' "${repo_versions}" \
11+
| awk '{print $2}' | sed 's|refs/tags/||' \
12+
| grep -E '^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9]+)?$' \
13+
| sort -V | tail -n1
14+
}
15+
16+
# Tests the tag-resolution pipeline used by src/copilot-cli/install.sh for the
17+
# "prerelease" channel.
18+
19+
check "copilot binary is on PATH" which copilot
20+
check "copilot reports a version" bash -c "copilot -v"
21+
22+
result1="$(resolve_prerelease_version $'abc1234\trefs/tags/v1.0.1\ndef5678\trefs/tags/v1.0.9\nghi9012\trefs/tags/v1.0.10\njkl3456\trefs/tags/v1.0.45\nmno7890\trefs/tags/v1.0.2\n')"
23+
check "picks highest version (v1.0.45)" bash -c "[ '${result1}' = 'v1.0.45' ]"
24+
25+
result2="$(resolve_prerelease_version $'abc1234\trefs/tags/v1.0.44\ndef5678\trefs/tags/v1.0.45-1\nghi9012\trefs/tags/v1.0.45-10\njkl3456\trefs/tags/v1.0.45-2\nmno7890\trefs/tags/v1.0.45\n')"
26+
check "picks highest prerelease (v1.0.45-10)" bash -c "[ '${result2}' = 'v1.0.45-10' ]"
27+
28+
result3="$(resolve_prerelease_version $'abc1234\trefs/tags/latest\ndef5678\trefs/tags/v1.0.3\nghi9012\trefs/tags/nightly\njkl3456\trefs/tags/v1.0.20\n')"
29+
check "picks highest version ignoring non-version tags (v1.0.20)" bash -c "[ '${result3}' = 'v1.0.20' ]"
30+
31+
# Report result
32+
reportResults

test/copilot-cli/scenarios.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"resolve_prerelease_version": {
3+
"image": "ubuntu:noble",
4+
"features": {
5+
"copilot-cli": {
6+
"version": "latest"
7+
}
8+
}
9+
},
10+
"install_prerelease": {
11+
"image": "ubuntu:noble",
12+
"features": {
13+
"copilot-cli": {
14+
"version": "prerelease"
15+
}
16+
}
17+
}
18+
}

0 commit comments

Comments
 (0)