diff --git a/.github/deps/Linux/bin/parallelize b/.github/deps/Linux/amd64/bin/parallelize similarity index 100% rename from .github/deps/Linux/bin/parallelize rename to .github/deps/Linux/amd64/bin/parallelize diff --git a/.github/deps/Linux/arm64/bin/parallelize b/.github/deps/Linux/arm64/bin/parallelize new file mode 100755 index 0000000000..d0f0d1eb4e Binary files /dev/null and b/.github/deps/Linux/arm64/bin/parallelize differ diff --git a/.github/deps/Windows/bin/parallelize.exe b/.github/deps/Windows/amd64/bin/parallelize.exe similarity index 100% rename from .github/deps/Windows/bin/parallelize.exe rename to .github/deps/Windows/amd64/bin/parallelize.exe diff --git a/.github/deps/macOS/bin/parallelize b/.github/deps/macOS/amd64/bin/parallelize similarity index 100% rename from .github/deps/macOS/bin/parallelize rename to .github/deps/macOS/amd64/bin/parallelize diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b2d65094d7..6f82f16b26 100755 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -41,6 +41,7 @@ jobs: - {os: ubuntu-latest} - {os: macos-13, shell: zsh} - {os: windows-2019} + - {os: ubuntu-24.04-arm} fail-fast: false runs-on: ${{ matrix.sys.os }} env: @@ -74,19 +75,30 @@ jobs: # === Install gotestfmt === - name: Set up gotestfmt - uses: gotesttools/gotestfmt-action@v2 - with: - token: ${{ secrets.GITHUB_TOKEN }} + shell: bash + run: go install github.com/gotesttools/gotestfmt/v2/cmd/gotestfmt@latest - # === Install State Tool === name: Install State Tool uses: ActiveState/setup-state-tool@v1 + if: "!contains(matrix.sys.os, 'arm')" + + - # === Install State Tool (ARM64) === + name: Install State Tool (ARM64) + if: contains(matrix.sys.os, 'arm') + shell: bash + run: | + ./installers/install.sh -b beta + echo "$HOME/.local/ActiveState/StateTool/beta/bin" >> $GITHUB_PATH + "$HOME/.local/ActiveState/StateTool/beta/bin/state" config set optin.unstable true - # === Setup === name: Setup shell: bash run: | - bin=$(pwd)/.github/deps/${{ runner.os }}/bin + arch="amd64" + if [[ ${{ contains(matrix.sys.os, 'arm') }} = true ]]; then arch="arm64"; fi + bin=$(pwd)/.github/deps/${{ runner.os }}/$arch/bin echo "Adding $bin to PATH" echo "$bin" >> $GITHUB_PATH @@ -125,7 +137,6 @@ jobs: shell: bash timeout-minutes: 15 run: | - export PATH="$(pwd)/.github/deps/${{ runner.os }}/bin:$PATH" parallelize "$(cat <<'EOF' [ { @@ -262,7 +273,7 @@ jobs: - # === Configure AWS credentials == name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v2 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} role-session-name: ${{ env.AWS_ROLE_SESSION_NAME }} @@ -325,6 +336,10 @@ jobs: fi else TEST_SUITE_TAGS="all" + if [[ ${{ contains(matrix.sys.os, 'arm') }} = true ]]; then + echo "Skipping integration tests on ARM" + exit 0 + fi fi echo "Running integration tests with tags: $TEST_SUITE_TAGS (empty means every test not specifically tagged)" @@ -483,7 +498,7 @@ jobs: - # === Configure AWS credentials == name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v2 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} role-session-name: ${{ env.AWS_ROLE_SESSION_NAME }} @@ -511,3 +526,4 @@ jobs: session-build-ubuntu-20.04 session-build-macos-11 session-build-windows-2019 + session-build-ubuntu-24.04-arm diff --git a/activestate.generators.yaml b/activestate.generators.yaml index e84712a169..51d18c60c3 100644 --- a/activestate.generators.yaml +++ b/activestate.generators.yaml @@ -1,6 +1,7 @@ scripts: - name: generate-api-client language: bash + standalone: true description: Generates the mono-api client files value: | echo "IMPORTANT!!! mono API and inventory API have to be in sync. Consider running state run generate-inventory-client" @@ -10,6 +11,7 @@ scripts: popd - name: generate-secrets-client language: bash + standalone: true description: Generates the secrets-api client files value: | WD=$(pwd) @@ -18,6 +20,7 @@ scripts: popd - name: generate-headchef-client language: bash + standalone: true description: Generates the headchef-api client files value: | WD=$(pwd) @@ -26,6 +29,7 @@ scripts: popd - name: generate-logstreamer-client language: bash + standalone: true description: Generates the buildlog-streamer client files value: | WD=$(pwd) @@ -34,6 +38,7 @@ scripts: popd - name: generate-inventory-client language: bash + standalone: true description: Generates the inventory-api client files value: | echo "IMPORTANT!!! mono API and inventory API have to be in sync. Consider running state run generate-api-client" @@ -43,6 +48,7 @@ scripts: popd - name: generate-clients language: bash + standalone: true description: Generates all api clients value: | $scripts.generate-api-client.path() @@ -55,6 +61,7 @@ scripts: value: python3 scripts/locale-generator.py - name: generate-payload language: bash + standalone: true description: Generate payload for installer / update archives value: | set -e @@ -64,10 +71,10 @@ scripts: go run ./scripts/ci/payload-generator/main.go "$@" - name: generate-update language: bash + standalone: true description: Generate update files value: | set -e - export GOARCH=${1:-amd64} $constants.SET_ENV $scripts.generate-payload.path() @@ -79,9 +86,11 @@ scripts: go run scripts/ci/update-generator/main.go -o ./build/update - name: generate-remote-install-deployment language: bash + standalone: true value: go run scripts/ci/deploy-generator/remote-installer/main.go "$@" - name: generate-graph language: bash + standalone: true description: Generates graph server and client files value: | set -e diff --git a/activestate.yaml b/activestate.yaml index 8d021d9ce1..613016b1f2 100644 --- a/activestate.yaml +++ b/activestate.yaml @@ -114,17 +114,6 @@ scripts: popd > /dev/null fi go build -tags "$GO_BUILD_TAGS" -o $BUILD_TARGET_DIR/$constants.BUILD_TARGET $constants.CLI_BUILDFLAGS $constants.CLI_PKGS - - name: build-for - language: bash - standalone: true - description: Builds the project with the specified OS as the target OS. (valid values darwin, linux, windows) - value: | - set -e - $constants.SET_ENV - export GOOS=${1} - export GOARCH=amd64 - [ -z "${2}" ] && >&2 echo "must provide output file as 2nd arg" && exit 1 - go build -tags "internal $GO_BUILD_TAGS" -o ${2} $constants.CLI_BUILDFLAGS $constants.CLI_PKGS - name: build-svc language: bash standalone: true @@ -260,46 +249,10 @@ scripts: standalone: true description: Generates our github workflows value: | - $scripts.build-for.path() "windows" ./.github/deps/Windows/bin/state.exe - $scripts.build-for.path() "linux" ./.github/deps/Linux/bin/state - $scripts.build-for.path() "darwin" ./.github/deps/macOS/bin/state - - GOOS=windows go build -o .github/deps/Windows/bin/parallelize.exe github.com/ActiveState/cli/scripts/ci/parallelize/ - GOOS=linux go build -o .github/deps/Linux/bin/parallelize github.com/ActiveState/cli/scripts/ci/parallelize/ - GOOS=darwin go build -o .github/deps/macOS/bin/parallelize github.com/ActiveState/cli/scripts/ci/parallelize/ - - name: update-workflow-assets - language: bash - standalone: true - description: Generates our github workflows - value: | - [ -z "${2}" ] && >&2 echo "Usage: update-workflow-assets [branch] [version]" && exit 1 - - tmpDir=$(mktemp -d) - pushd $tmpDir - wget https://state-tool.s3.amazonaws.com/update/state/${1}/${2}/darwin-amd64/state-darwin-amd64-${2}.tar.gz - tar xzf state-darwin-amd64-${2}.tar.gz - cp -Rfv state-install/bin/state $project.path()/.github/deps/macOS/bin - cp -Rfv state-install/bin/state-svc $project.path()/.github/deps/macOS/bin - popd - rm -Rf $tmpDir - - tmpDir=$(mktemp -d) - pushd $tmpDir - wget https://state-tool.s3.amazonaws.com/update/state/${1}/${2}/linux-amd64/state-linux-amd64-${2}.tar.gz - tar xzf state-linux-amd64-${2}.tar.gz - cp -Rfv state-install/bin/state $project.path()/.github/deps/Linux/bin - cp -Rfv state-install/bin/state-svc $project.path()/.github/deps/Linux/bin - popd - rm -Rf $tmpDir - - tmpDir=$(mktemp -d) - pushd $tmpDir - wget https://state-tool.s3.amazonaws.com/update/state/${1}/${2}/windows-amd64/state-windows-amd64-${2}.zip - unzip state-windows-amd64-${2}.zip - cp -Rfv state-install/bin/state.exe $project.path()/.github/deps/Windows/bin - cp -Rfv state-install/bin/state-svc.exe $project.path()/.github/deps/Windows/bin - popd - rm -Rf $tmpDir + GOOS=windows go build -o .github/deps/Windows/amd64/bin/parallelize.exe github.com/ActiveState/cli/scripts/ci/parallelize/ + GOOS=linux go build -o .github/deps/Linux/amd64/bin/parallelize github.com/ActiveState/cli/scripts/ci/parallelize/ + GOOS=linux GOARCH=arm64 go build -o .github/deps/Linux/arm64/bin/parallelize github.com/ActiveState/cli/scripts/ci/parallelize/ + GOOS=darwin go build -o .github/deps/macOS/amd64/bin/parallelize github.com/ActiveState/cli/scripts/ci/parallelize/ - name: test language: bash standalone: true diff --git a/cmd/state-installer/test/integration/installer_int_test.go b/cmd/state-installer/test/integration/installer_int_test.go index d55adf8869..ee300d9779 100644 --- a/cmd/state-installer/test/integration/installer_int_test.go +++ b/cmd/state-installer/test/integration/installer_int_test.go @@ -167,6 +167,9 @@ func (suite *InstallerIntegrationTestSuite) TestInstallNoErrorTips() { } func (suite *InstallerIntegrationTestSuite) TestInstallErrorTips() { + if runtime.GOARCH == "arm64" { + suite.T().Skip("ARM platform projects are not supported yet") + } suite.OnlyRunForTags(tagsuite.Installer, tagsuite.Critical) ts := e2e.New(suite.T(), false) defer ts.Close() diff --git a/installers/install.sh b/installers/install.sh index 978662623e..8a9143f80a 100755 --- a/installers/install.sh +++ b/installers/install.sh @@ -69,6 +69,9 @@ error () { case `uname -s` in Linux) OS="linux" + ARCH="amd64" + arch="`uname -m`" + if [ $arch = "arm64" -o $arch = "aarch64" ]; then ARCH="arm64"; fi DOWNLOADEXT=".tar.gz" ;; *BSD) @@ -78,11 +81,13 @@ Linux) ;; Darwin) OS="darwin" + ARCH="amd64" DOWNLOADEXT=".tar.gz" SHA256SUM="shasum -a 256" ;; MINGW*|MSYS*) OS="windows" + ARCH="amd64" DOWNLOADEXT=".zip" BINARYEXT=".exe" ;; @@ -113,18 +118,18 @@ mkdir -p "$INSTALLERTMPDIR" if [ -z "$VERSION" ]; then # If the user did not specify a version, formulate a query to fetch the JSON info of the latest # version, including where it is. - JSONURL="$BASE_INFO_URL?channel=$CHANNEL&source=install&platform=$OS" + JSONURL="$BASE_INFO_URL?channel=$CHANNEL&source=install&platform=$OS&arch=$ARCH" elif [ -z "`echo $VERSION | grep -o '\-SHA'`" ]; then # If the user specified a partial version (i.e. no SHA), formulate a query to fetch the JSON info # of that version's latest SHA, including where it is. VERSIONNOSHA="$VERSION" VERSION="" - JSONURL="$BASE_INFO_URL?channel=$CHANNEL&source=install&platform=$OS&target-version=$VERSIONNOSHA" + JSONURL="$BASE_INFO_URL?channel=$CHANNEL&source=install&platform=$OS&arch=$ARCH&target-version=$VERSIONNOSHA" else # If the user specified a full version with SHA, formulate a query to fetch the JSON info of that # version. VERSIONNOSHA="`echo $VERSION | sed 's/-SHA.*$//'`" - JSONURL="$BASE_INFO_URL?channel=$CHANNEL&source=install&platform=$OS&target-version=$VERSIONNOSHA" + JSONURL="$BASE_INFO_URL?channel=$CHANNEL&source=install&platform=$OS&arch=$ARCH&target-version=$VERSIONNOSHA" fi # Fetch version info. @@ -157,13 +162,13 @@ else error "Unknown version: $VERSION" exit 1 fi - RELURL="$CHANNEL/$VERSIONNOSHA/$OS-amd64/state-$OS-amd64-$VERSION$DOWNLOADEXT" + RELURL="$CHANNEL/$VERSIONNOSHA/$OS-$ARCH/state-$OS-$ARCH-$VERSION$DOWNLOADEXT" fi # Fetch the requested or latest version. progress "Preparing Installer for State Tool Package Manager version $VERSION" STATEURL="$BASE_FILE_URL/$RELURL" -ARCHIVE="$OS-amd64$DOWNLOADEXT" +ARCHIVE="$OS-$ARCH$DOWNLOADEXT" $FETCH $INSTALLERTMPDIR/$ARCHIVE $STATEURL # wget and curl differ on how to handle AWS' "Forbidden" result for unknown versions. # wget will exit with nonzero status. curl simply creates an XML file with the forbidden error. diff --git a/internal/updater/checker.go b/internal/updater/checker.go index b643293f15..2572cc281d 100644 --- a/internal/updater/checker.go +++ b/internal/updater/checker.go @@ -72,11 +72,12 @@ func (u *Checker) CheckFor(desiredChannel, desiredVersion string) (*AvailableUpd return info, nil } -func (u *Checker) infoURL(tag, desiredVersion, branchName, platform string) string { +func (u *Checker) infoURL(tag, desiredVersion, branchName, platform, arch string) string { v := make(url.Values) v.Set("channel", branchName) v.Set("platform", platform) v.Set("source", string(u.InvocationSource)) + v.Set("arch", arch) if desiredVersion != "" { v.Set("target-version", desiredVersion) @@ -91,7 +92,7 @@ func (u *Checker) infoURL(tag, desiredVersion, branchName, platform string) stri func (u *Checker) getUpdateInfo(desiredChannel, desiredVersion string) (*AvailableUpdate, error) { tag := u.cfg.GetString(CfgUpdateTag) - infoURL := u.infoURL(tag, desiredVersion, desiredChannel, runtime.GOOS) + infoURL := u.infoURL(tag, desiredVersion, desiredChannel, runtime.GOOS, runtime.GOARCH) logging.Debug("Getting update info: %s", infoURL) var info *AvailableUpdate diff --git a/pkg/sysinfo/sysinfo_linux_arm.go b/pkg/sysinfo/sysinfo_linux_arm64.go similarity index 100% rename from pkg/sysinfo/sysinfo_linux_arm.go rename to pkg/sysinfo/sysinfo_linux_arm64.go diff --git a/test/integration/install_scripts_int_test.go b/test/integration/install_scripts_int_test.go index 7c27fd4cd6..cc16979b89 100644 --- a/test/integration/install_scripts_int_test.go +++ b/test/integration/install_scripts_int_test.go @@ -5,6 +5,7 @@ import ( "fmt" "path/filepath" "runtime" + "strings" "testing" "github.com/ActiveState/cli/internal/config" @@ -48,6 +49,9 @@ func (suite *InstallScriptsIntegrationTestSuite) TestInstall() { } for _, tt := range tests { + if runtime.GOARCH == "arm64" && strings.Contains(tt.Name, "activate") { + continue // ARM platform projects are not supported yet + } suite.Run(fmt.Sprintf("%s (%s@%s)", tt.Name, tt.Version, tt.Channel), func() { ts := e2e.New(suite.T(), false) defer ts.Close() diff --git a/test/integration/update_int_test.go b/test/integration/update_int_test.go index 8bffc3a167..e3da44e9d4 100644 --- a/test/integration/update_int_test.go +++ b/test/integration/update_int_test.go @@ -357,6 +357,9 @@ func (suite *UpdateIntegrationTestSuite) installLatestReleaseVersion(ts *e2e.Ses } func (suite *UpdateIntegrationTestSuite) TestAutoUpdateToCurrent() { + if runtime.GOARCH == "arm64" { + suite.T().Skip("There is no official ARM release for install.sh yet") + } suite.OnlyRunForTags(tagsuite.Update, tagsuite.Critical) ts := e2e.New(suite.T(), false) @@ -376,6 +379,9 @@ func (suite *UpdateIntegrationTestSuite) TestUpdateToCurrent() { // Feel free to drop this once the release channel is no longer on 0.29 suite.T().Skip("Updating from release 0.29 to 0.30 is not covered due to how 0.29 did updates (async)") } + if runtime.GOARCH == "arm64" { + suite.T().Skip("There is no official ARM release for install.sh yet") + } suite.OnlyRunForTags(tagsuite.Update, tagsuite.Critical) ts := e2e.New(suite.T(), false) diff --git a/test/integration/update_lock_int_test.go b/test/integration/update_lock_int_test.go index 471c4b8527..3ff83ffbd7 100644 --- a/test/integration/update_lock_int_test.go +++ b/test/integration/update_lock_int_test.go @@ -5,6 +5,7 @@ import ( "os" "path/filepath" "regexp" + "runtime" "github.com/ActiveState/cli/internal/config" "github.com/ActiveState/cli/internal/constants" @@ -16,6 +17,9 @@ import ( ) func (suite *UpdateIntegrationTestSuite) TestLocked() { + if runtime.GOARCH == "arm64" { + suite.T().Skip("There is no official ARM release for install.sh yet") + } suite.OnlyRunForTags(tagsuite.Update) suite.T().Skip("Requires https://www.pivotaltracker.com/story/show/177827538 and needs to be adapted.") pjfile := projectfile.Project{ @@ -44,6 +48,9 @@ func (suite *UpdateIntegrationTestSuite) TestLocked() { } func (suite *UpdateIntegrationTestSuite) TestLockedChannel() { + if runtime.GOARCH == "arm64" { + suite.T().Skip("There is no official ARM release for install.sh yet") + } suite.OnlyRunForTags(tagsuite.Update) targetBranch := "release" if constants.ChannelName == "release" {