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
3 changes: 3 additions & 0 deletions .github/workflows/pull-request-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

jobs:
ci-lint:
runs-on: ubuntu-latest-4cores-16GB

Check failure on line 18 in .github/workflows/pull-request-main.yml

View workflow job for this annotation

GitHub Actions / ci-lint-misc

[actionlint] reported by reviewdog 🐶 label "ubuntu-latest-4cores-16GB" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2022", "windows-2019", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-22.04", "ubuntu-20.04", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-14.0", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "macos-13.0", "macos-12-xl", "macos-12-xlarge", "macos-12-large", "macos-12", "macos-12.0", "macos-11", "macos-11.0", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file [runner-label] Raw Output: .github/workflows/pull-request-main.yml:18:14: label "ubuntu-latest-4cores-16GB" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2022", "windows-2019", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-22.04", "ubuntu-20.04", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-14.0", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "macos-13.0", "macos-12-xl", "macos-12-xlarge", "macos-12-large", "macos-12", "macos-12.0", "macos-11", "macos-11.0", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file [runner-label]
permissions:
id-token: write
contents: read
Expand Down Expand Up @@ -48,6 +48,9 @@
- name: Verify install.sh embedded release public key
run: bash install/check_embedded_key.sh

- name: Verify install.sh linux asset suffix helpers
run: bash install/linux_asset_suffix_test.sh

ci-test-unit:
runs-on: ubuntu-latest
permissions:
Expand Down Expand Up @@ -118,7 +121,7 @@
artifact-name: go-test-${{ matrix.os }}

ci-test-system:
runs-on: ubuntu-latest-4cores-16GB

Check failure on line 124 in .github/workflows/pull-request-main.yml

View workflow job for this annotation

GitHub Actions / ci-lint-misc

[actionlint] reported by reviewdog 🐶 label "ubuntu-latest-4cores-16GB" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2022", "windows-2019", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-22.04", "ubuntu-20.04", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-14.0", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "macos-13.0", "macos-12-xl", "macos-12-xlarge", "macos-12-large", "macos-12", "macos-12.0", "macos-11", "macos-11.0", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file [runner-label] Raw Output: .github/workflows/pull-request-main.yml:124:14: label "ubuntu-latest-4cores-16GB" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2022", "windows-2019", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-22.04", "ubuntu-20.04", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-14.0", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "macos-13.0", "macos-12-xl", "macos-12-xlarge", "macos-12-large", "macos-12", "macos-12.0", "macos-11", "macos-11.0", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file [runner-label]
if: false # Disable system test untill we have a version of the test that works with the new CRE CLI (Smartcon)
environment: system-test
permissions:
Expand Down
61 changes: 61 additions & 0 deletions cmd/update/linux_asset_suffix_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//go:build linux

package update

import (
"fmt"
"os/exec"
"regexp"
"strings"

"github.com/Masterminds/semver/v3"
)

const (
linuxLdd235Suffix = "_ldd2-35"
linuxGlibcThreshold = "2.36"
)

var glibcVersionPattern = regexp.MustCompile(`(\d+\.\d+)(?:\.\d+)?`)

func linuxAssetSuffix() string {
out, err := exec.Command("ldd", "--version").Output() // #nosec G204 -- fixed args, standard glibc probe
if err != nil {
return ""
}

version, err := parseGlibcVersionFromLddOutput(string(out))
if err != nil {
return ""
}

threshold, err := semver.NewVersion(linuxGlibcThreshold)
if err != nil {
return ""
}
if version.LessThan(threshold) {
return linuxLdd235Suffix
}
return ""
}

func parseGlibcVersionFromLddOutput(output string) (*semver.Version, error) {
firstLine := strings.TrimSpace(output)
if idx := strings.IndexByte(firstLine, '\n'); idx >= 0 {
firstLine = firstLine[:idx]
}
if firstLine == "" {
return nil, fmt.Errorf("empty ldd --version output")
}

matches := glibcVersionPattern.FindAllString(firstLine, -1)
if len(matches) == 0 {
return nil, fmt.Errorf("could not parse glibc version from %q", firstLine)
}

version, err := semver.NewVersion(matches[len(matches)-1])
if err != nil {
return nil, fmt.Errorf("parse glibc version %q: %w", matches[len(matches)-1], err)
}
return version, nil
}
89 changes: 89 additions & 0 deletions cmd/update/linux_asset_suffix_linux_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
//go:build linux

package update

import (
"testing"

"github.com/Masterminds/semver/v3"
"github.com/stretchr/testify/require"
)

func TestParseGlibcVersionFromLddOutput(t *testing.T) {
t.Parallel()

tests := []struct {
name string
output string
want string
wantErr bool
}{
{
name: "ubuntu 22.04",
output: "ldd (Ubuntu GLIBC 2.35-0ubuntu3.8) 2.35\nCopyright (C) 2022 Free Software Foundation, Inc.\n",
want: "2.35",
},
{
name: "ubuntu 24.04",
output: "ldd (Ubuntu GLIBC 2.39-0ubuntu8.4) 2.39\n",
want: "2.39",
},
{
name: "rhel style",
output: "ldd (GNU libc) 2.34\n",
want: "2.34",
},
{
name: "empty",
output: "",
wantErr: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
got, err := parseGlibcVersionFromLddOutput(tt.output)
if tt.wantErr {
require.Error(t, err)
return
}
require.NoError(t, err)
want, err := semver.NewVersion(tt.want)
require.NoError(t, err)
require.True(t, got.Equal(want))
})
}
}

func TestLinuxAssetSuffixFromGlibcVersion(t *testing.T) {
t.Parallel()

tests := []struct {
output string
want string
}{
{
output: "ldd (Ubuntu GLIBC 2.35-0ubuntu3.8) 2.35\n",
want: linuxLdd235Suffix,
},
{
output: "ldd (Ubuntu GLIBC 2.39-0ubuntu8.4) 2.39\n",
want: "",
},
}

threshold, err := semver.NewVersion(linuxGlibcThreshold)
require.NoError(t, err)

for _, tt := range tests {
version, err := parseGlibcVersionFromLddOutput(tt.output)
require.NoError(t, err)

suffix := ""
if version.LessThan(threshold) {
suffix = linuxLdd235Suffix
}
require.Equal(t, tt.want, suffix)
}
}
7 changes: 7 additions & 0 deletions cmd/update/linux_asset_suffix_stub.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//go:build !linux

package update

func linuxAssetSuffix() string {
return ""
}
15 changes: 8 additions & 7 deletions cmd/update/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func getLatestTag() (string, error) {
return info.TagName, nil
}

func getAssetName() (asset string, platform string, archName string, err error) {
func getAssetName() (asset string, platform string, archName string, linuxSuffix string, err error) {
osName := osruntime.GOOS
arch := osruntime.GOARCH
var ext string
Expand All @@ -68,11 +68,12 @@ func getAssetName() (asset string, platform string, archName string, err error)
case "linux":
platform = "linux"
ext = ".tar.gz"
linuxSuffix = linuxAssetSuffix()
case "windows":
platform = "windows"
ext = ".zip"
default:
return "", "", "", fmt.Errorf("unsupported OS: %s", osName)
return "", "", "", "", fmt.Errorf("unsupported OS: %s", osName)
}
switch arch {
case "amd64", "x86_64":
Expand All @@ -84,10 +85,10 @@ func getAssetName() (asset string, platform string, archName string, err error)
archName = "arm64"
}
default:
return "", "", "", fmt.Errorf("unsupported architecture: %s", arch)
return "", "", "", "", fmt.Errorf("unsupported architecture: %s", arch)
}
asset = fmt.Sprintf("%s_%s_%s%s", cliName, platform, archName, ext)
return asset, platform, archName, nil
asset = fmt.Sprintf("%s_%s_%s%s%s", cliName, platform, archName, linuxSuffix, ext)
return asset, platform, archName, linuxSuffix, nil
}

func downloadFile(url, dest, message string) error {
Expand Down Expand Up @@ -335,7 +336,7 @@ func Run(currentVersion string) error {
}

// If we're here, an update is needed.
asset, platform, archName, err := getAssetName()
asset, platform, archName, linuxSuffix, err := getAssetName()
if err != nil {
spinner.Stop()
return fmt.Errorf("error determining asset name: %w", err)
Expand Down Expand Up @@ -369,7 +370,7 @@ func Run(currentVersion string) error {

var sigPath string
if platform == "linux" {
sigAsset := getSigAssetName(platform, archName)
sigAsset := getSigAssetName(platform, archName, linuxSuffix)
sigPath = filepath.Join(tmpDir, sigAsset)
sigURL := fmt.Sprintf("https://github.com/%s/releases/download/%s/%s", repo, tag, sigAsset)
sigDownloadMsg := fmt.Sprintf("Downloading signature for %s...", tag)
Expand Down
4 changes: 2 additions & 2 deletions cmd/update/update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func TestRun_abortsWhenSignatureVerificationFails(t *testing.T) {
httpmock.ActivateNonDefault(httpClient)
t.Cleanup(httpmock.DeactivateAndReset)

asset, platform, archName, err := getAssetName()
asset, platform, archName, linuxSuffix, err := getAssetName()
require.NoError(t, err)

tag := "v99.0.0-test"
Expand All @@ -39,7 +39,7 @@ func TestRun_abortsWhenSignatureVerificationFails(t *testing.T) {
)

if platform == "linux" {
sigAsset := getSigAssetName(platform, archName)
sigAsset := getSigAssetName(platform, archName, linuxSuffix)
sigURL := "https://github.com/smartcontractkit/cre-cli/releases/download/" + tag + "/" + sigAsset
httpmock.RegisterResponder("GET", sigURL,
func(_ *http.Request) (*http.Response, error) {
Expand Down
4 changes: 2 additions & 2 deletions cmd/update/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ const (
codesignIdentifier = "com.smartcontract.cre.cli"
)

func getSigAssetName(platform, archName string) string {
return "cre_" + platform + "_" + archName + ".sig"
func getSigAssetName(platform, archName, linuxSuffix string) string {
return "cre_" + platform + "_" + archName + linuxSuffix + ".sig"
}
7 changes: 4 additions & 3 deletions cmd/update/verify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ import (
)

func TestGetSigAssetName(t *testing.T) {
require.Equal(t, "cre_linux_amd64.sig", getSigAssetName("linux", "amd64"))
require.Equal(t, "cre_linux_amd64.sig", getSigAssetName("linux", "amd64", ""))
require.Equal(t, "cre_linux_amd64_ldd2-35.sig", getSigAssetName("linux", "amd64", "_ldd2-35"))
}

func TestGetAssetName(t *testing.T) {
asset, platform, archName, err := getAssetName()
asset, platform, archName, linuxSuffix, err := getAssetName()
require.NoError(t, err)
require.NotEmpty(t, asset)
require.NotEmpty(t, platform)
require.NotEmpty(t, archName)
require.Contains(t, asset, "cre_"+platform+"_"+archName)
require.Contains(t, asset, "cre_"+platform+"_"+archName+linuxSuffix)
}
58 changes: 56 additions & 2 deletions install/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,52 @@ verify_release_binary() {
esac
}

LINUX_LDD235_SUFFIX="_ldd2-35"
LINUX_GLIBC_THRESHOLD="2.36"

parse_glibc_version_from_ldd_output() {
local output=$1
local first_line version

first_line=$(printf '%s' "$output" | head -n1)
version=$(printf '%s' "$first_line" | grep -oE '[0-9]+\.[0-9]+' | tail -n1)
if [ -z "$version" ]; then
return 1
fi
printf '%s' "$version"
}

version_lt() {
local left=$1
local right=$2
[ "$(printf '%s\n' "$left" "$right" | sort -V | head -n1)" = "$left" ] && [ "$left" != "$right" ]
}

linux_asset_suffix() {
local ldd_output version

if [ "$PLATFORM" != "linux" ]; then
printf ''
return
fi

ldd_output=$(ldd --version 2>/dev/null | head -n1) || {
printf ''
return
}

version=$(parse_glibc_version_from_ldd_output "$ldd_output") || {
printf ''
return
}

if version_lt "$version" "$LINUX_GLIBC_THRESHOLD"; then
printf '%s' "$LINUX_LDD235_SUFFIX"
else
printf ''
fi
}

tildify() {
if [[ $1 = $HOME/* ]]; then
local replacement=\~/
Expand Down Expand Up @@ -321,7 +367,15 @@ else
fi

# 4. Construct Download URL and Download asset
ASSET="${cli_name}_${PLATFORM}_${ARCH_NAME}"
LINUX_SUFFIX=""
if [ "$PLATFORM" = "linux" ]; then
LINUX_SUFFIX=$(linux_asset_suffix)
if [ -n "$LINUX_SUFFIX" ]; then
echo "Using glibc-compatible build for older Linux (ldd2-35)..."
fi
fi

ASSET="${cli_name}_${PLATFORM}_${ARCH_NAME}${LINUX_SUFFIX}"
# Determine the file extension based on OS
if [ "$PLATFORM" = "linux" ]; then
ASSET="${ASSET}.tar.gz"
Expand All @@ -343,7 +397,7 @@ SIG_PATH=""

if [ "$PLATFORM" = "linux" ]; then
check_command "gpg"
SIG_ASSET="${cli_name}_${PLATFORM}_${ARCH_NAME}.sig"
SIG_ASSET="${cli_name}_${PLATFORM}_${ARCH_NAME}${LINUX_SUFFIX}.sig"
SIG_URL="https://github.com/$github_repo/releases/download/$LATEST_TAG/$SIG_ASSET"
SIG_PATH="$TMP_DIR/$SIG_ASSET"
curl --fail --location --progress-bar "$SIG_URL" --output "$SIG_PATH" ||
Expand Down
Loading
Loading