Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
7017cd0
Update version.txt
mitchell-as Nov 19, 2025
c15fb2b
Replace mholt/archiver with mholt/archives.
mitchell-as Nov 20, 2025
6cd746c
Pass blob readers to unarchivers rather than having a dedicated blob …
mitchell-as Nov 20, 2025
a45a00f
Fixed unarchiving of links.
mitchell-as Nov 20, 2025
b1597d5
Try to fix hardlink failures.
mitchell-as Nov 20, 2025
c5ae974
Use correct []byte reader interface.
mitchell-as Nov 20, 2025
4c6c55c
ProxyReader needs to implement io.Seeker for unpacking zip archives.
mitchell-as Nov 20, 2025
e46897b
Merge pull request #3760 from ActiveState/mitchell/cp-1080
mitchell-as Nov 24, 2025
e23a2c2
Address CVEs.
mitchell-as Nov 24, 2025
d62a88f
Merge pull request #3759 from ActiveState/mitchell/cp-1251
mitchell-as Nov 24, 2025
c28680c
Placate check-format
mitchell-as Nov 24, 2025
d117943
Merge pull request #3762 from ActiveState/mitchell/placate-check-format
mitchell-as Nov 24, 2025
f909b96
Update macOS runner.
mitchell-as Nov 24, 2025
343ef66
Merge pull request #3764 from ActiveState/mitchell/cp-1253
mitchell-as Nov 24, 2025
bc9d936
Updated golangci-lint dev dependency and migrated config.
mitchell-as Nov 25, 2025
72a5057
Allow performance tests to run for up to a minute.
mitchell-as Nov 25, 2025
12e2f60
Merge pull request #3767 from ActiveState/mitchell/cp-1130
mitchell-as Nov 26, 2025
d9b27fd
Merge pull request #3766 from ActiveState/mitchell/cp-1171
mitchell-as Dec 1, 2025
66ba1bf
Updated changelog for 0.48.1.
mitchell-as Dec 3, 2025
5f3918d
Merge pull request #3770 from ActiveState/mitchell/0-48-1-changelog
mitchell-as Dec 3, 2025
560d8fb
Updated GitHub Actions to Go 1.24.
mitchell-as Dec 3, 2025
565fe45
Merge pull request #3773 from ActiveState/mitchell/github-actions-go-…
mitchell-as Dec 3, 2025
4f1a2c1
Updated Go to 1.24.11 to remediate CVEs.
mitchell-as Dec 4, 2025
9c6c310
Merge pull request #3776 from ActiveState/mitchell/cp-1261
mitchell-as Dec 4, 2025
b8cf48e
Merge branch 'beta' into version/0-48-1-RC1
mitchell-as Dec 4, 2025
09b5348
Avoid concurrent map read/write.
mitchell-as Dec 8, 2025
e8550d2
Updated changelog.
mitchell-as Dec 8, 2025
8aea71e
Merge pull request #3780 from ActiveState/mitchell/cp-1265
mitchell-as Dec 8, 2025
c7295d8
Updated to 0.48.1-RC2
mitchell-as Jan 5, 2026
7215bcf
Fixed cache dir path on Windows.
mitchell-as Jan 5, 2026
3aae73f
Fixed old compile error.
mitchell-as Jan 5, 2026
a15cff4
Merge pull request #3786 from ActiveState/mitchell/cp-1129-2
mitchell-as Dec 15, 2025
1c97a7b
Merge pull request #3787 from ActiveState/mitchell/cp-1144
mitchell-as Dec 16, 2025
935af57
Merge pull request #3788 from ActiveState/mitchell/cp-1276
mitchell-as Dec 18, 2025
1f00310
Merge pull request #3789 from ActiveState/mitchell/cp-1278
mitchell-as Dec 18, 2025
a578728
Merge pull request #3790 from ActiveState/mitchell/cp-1277
mitchell-as Dec 19, 2025
0017566
Merge pull request #3792 from ActiveState/mitchell/cp-1280
mitchell-as Dec 23, 2025
c2de887
Merge pull request #3794 from ActiveState/mitchell/cp-1278-2
mitchell-as Dec 23, 2025
9544da8
Merge pull request #3796 from ActiveState/mitchell/cp-1284-2
mitchell-as Dec 24, 2025
0b1efdc
Merge pull request #3798 from ActiveState/mitchell/cp-1288
mitchell-as Dec 29, 2025
e9e4128
Merge pull request #3800 from ActiveState/mitchell/cp-1290
mitchell-as Jan 5, 2026
e98783f
Merge pull request #3801 from ActiveState/mitchell/cp-1289
mitchell-as Jan 6, 2026
0bc5114
Updated changelog.
mitchell-as Jan 6, 2026
b80bc05
Merge pull request #3803 from ActiveState/mitchell/cp-1261
mitchell-as Jan 6, 2026
5fb2264
Merge branch 'beta' into version/0-48-1-RC2
mitchell-as Jan 6, 2026
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
5 changes: 2 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
# === OS Specific Job (runs on each OS) ===
os_specific:
name: ${{ matrix.sys.os }}
timeout-minutes: 90
timeout-minutes: 120
strategy:
matrix:
go-version:
Expand Down Expand Up @@ -327,15 +327,14 @@ jobs:
export TEST_SUITE_TAGS="$TEST_SUITE_TAGS"
TIMEOUT=30m
if [[ "$TEST_SUITE_TAGS" == "all" ]]; then
TIMEOUT=90m
TIMEOUT=120m
fi
SHELL='${{ matrix.sys.shell }}' go test -timeout $TIMEOUT -v `go list ./... | grep "integration"` -json 2>&1 | gotestfmt -hide empty-packages
continue-on-error: ${{ github.event_name == 'schedule' }}
env:
INTEGRATION_TEST_USERNAME: ${{ secrets.INTEGRATION_TEST_USERNAME }}
INTEGRATION_TEST_PASSWORD: ${{ secrets.INTEGRATION_TEST_PASSWORD }}
INTEGRATION_TEST_TOKEN: ${{ secrets.INTEGRATION_TEST_TOKEN }}
PLATFORM_API_TOKEN: ${{ secrets.PLATFORM_API_TOKEN }}

- # === Check if Unit Tests Failed ===
name: Check if Unit Tests Failed
Expand Down
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to
### Fixed

- Fixed occasional panic due to a concurrent map read/write during runtime setup.
- Fixed `state clean cache` from accidentally deleting State Tool binaries on Windows.

## 0.48.0

Expand Down
5 changes: 4 additions & 1 deletion cmd/state-svc/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ func main() {
}

if err := events.WaitForEvents(5*time.Second, rollbar.Wait, authentication.LegacyClose, logging.Close); err != nil {
logging.Warning("Failing to wait events")
// Note: logger is closed, so cannot log here. Also, the activate integration tests seem to be
// affected by a write to os.Stderr. Regardless, since state-svc runs in the background for
// the most part, we realistically will not see this error.
//fmt.Fprintf(os.Stderr, "Warning: failed to wait for events")
}
os.Exit(exitCode)
}()
Expand Down
5 changes: 4 additions & 1 deletion cmd/state-svc/test/integration/svc_int_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,10 @@ func (suite *SvcIntegrationTestSuite) TestStartDuplicateErrorOutput() {
func (suite *SvcIntegrationTestSuite) TestSingleSvc() {
suite.OnlyRunForTags(tagsuite.Service)
ts := e2e.New(suite.T(), false)
defer ts.Close()
// TODO: CP-1268 should remove this conditional.
if runtime.GOOS != "windows" || !condition.OnCI() {
defer ts.Close()
}

ts.SpawnCmdWithOpts(ts.SvcExe, e2e.OptArgs("stop"))
time.Sleep(2 * time.Second) // allow for some time to stop the existing available process
Expand Down
8 changes: 7 additions & 1 deletion internal/installation/storage/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,13 @@ func CachePath() string {
return path
}

return filepath.Join(BaseCachePath(), relativeCachePath())
cachePath = filepath.Join(BaseCachePath(), relativeCachePath())
if runtime.GOOS == "windows" {
// Explicitly append "cache" dir as the cachedir on Windows.
// It is the same as the local appdata dir (conflicts with config)
cachePath = filepath.Join(cachePath, "cache")
}
return cachePath
}

func GlobalBinDir() string {
Expand Down
2 changes: 1 addition & 1 deletion internal/installation/storage/storage_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ func BaseCachePath() string {
return cache
}

return filepath.Join(homeDir, "AppData", "Local", "cache")
return filepath.Join(homeDir, "AppData", "Local")
}
36 changes: 0 additions & 36 deletions internal/testhelpers/e2e/clean.go
Original file line number Diff line number Diff line change
@@ -1,31 +1,12 @@
package e2e

import (
"testing"

"github.com/ActiveState/cli/internal/errs"
"github.com/ActiveState/cli/pkg/platform/api/mono/mono_client/projects"
"github.com/ActiveState/cli/pkg/platform/api/mono/mono_client/users"
"github.com/ActiveState/cli/pkg/platform/api/mono/mono_models"
"github.com/ActiveState/cli/pkg/platform/authentication"
"github.com/ActiveState/cli/pkg/platform/model"
)

func cleanUser(t *testing.T, username string, auth *authentication.Auth) error {
projects, err := getProjects(username, auth)
if err != nil {
return err
}
for _, proj := range projects {
err = model.DeleteProject(username, proj.Name, auth)
if err != nil {
return err
}
}

return deleteUser(username, auth)
}

func getProjects(org string, auth *authentication.Auth) ([]*mono_models.Project, error) {
authClient, err := auth.Client()
if err != nil {
Expand All @@ -40,20 +21,3 @@ func getProjects(org string, auth *authentication.Auth) ([]*mono_models.Project,

return listProjectsOK.Payload, nil
}

func deleteUser(name string, auth *authentication.Auth) error {
authClient, err := auth.Client()
if err != nil {
return errs.Wrap(err, "Could not get auth client")
}

params := users.NewDeleteUserParams()
params.SetUsername(name)

_, err = authClient.Users.DeleteUser(params, auth.ClientAuth())
if err != nil {
return err
}

return nil
}
22 changes: 5 additions & 17 deletions internal/testhelpers/e2e/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,6 @@ type Session struct {
Env []string
retainDirs bool
createdProjects []*project.Namespaced
// users created during session
users []string
T *testing.T
Exe string
SvcExe string
Expand Down Expand Up @@ -542,11 +540,6 @@ func (s *Session) Close() error {

s.spawned = []*SpawnedCmd{}

if os.Getenv("PLATFORM_API_TOKEN") == "" {
s.T.Log("PLATFORM_API_TOKEN env var not set, not running suite tear down")
return nil
}

auth := authentication.New(cfg)

if os.Getenv(constants.APIHostEnvVarName) == "" {
Expand All @@ -560,9 +553,11 @@ func (s *Session) Close() error {
}

err = auth.AuthenticateWithModel(&mono_models.Credentials{
Token: os.Getenv("PLATFORM_API_TOKEN"),
Username: PersistentUsername,
Password: PersistentPassword,
})
if err != nil {
s.T.Errorf("Could not login: %v", errs.JoinMessage(err))
return err
}

Expand All @@ -586,14 +581,7 @@ func (s *Session) Close() error {
for _, proj := range s.createdProjects {
err := model.DeleteProject(proj.Owner, proj.Project, auth)
if err != nil {
s.T.Errorf("Could not delete project %s: %v", proj.Project, errs.JoinMessage(err))
}
}

for _, user := range s.users {
err := cleanUser(s.T, user, auth)
if err != nil {
s.T.Errorf("Could not delete user %s: %v", user, errs.JoinMessage(err))
s.T.Errorf("Could not delete project %s/%s: %v", proj.Owner, proj.Project, errs.JoinMessage(err))
}
}

Expand Down Expand Up @@ -799,7 +787,7 @@ func (s *Session) SetupRCFileCustom(subshell subshell.SubShell) {
rcFile, err := subshell.RcFile()
require.NoError(s.T, err)

if fileutils.TargetExists(filepath.Join(s.Dirs.HomeDir, filepath.Base(rcFile))) {
if fileutils.TargetExists(rcFile) && fileutils.TargetExists(filepath.Join(s.Dirs.HomeDir, filepath.Base(rcFile))) {
err = fileutils.CopyFile(rcFile, filepath.Join(s.Dirs.HomeDir, filepath.Base(rcFile)))
} else {
err = fileutils.Touch(filepath.Join(s.Dirs.HomeDir, filepath.Base(rcFile)))
Expand Down
2 changes: 1 addition & 1 deletion test/integration/buildscript_int_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ func (suite *BuildScriptIntegrationTestSuite) TestBuildScriptRequirementVersionA
cp.ExpectExitCode(0)

cp = ts.Spawn("install", "dotenv")
cp.Expect("Added: language/python/dotenv@Auto")
cp.Expect("Added: language/python/dotenv@Auto", e2e.RuntimeSolvingTimeoutOpt)
cp.ExpectExitCode(0)
}

Expand Down
12 changes: 7 additions & 5 deletions test/integration/commit_int_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (suite *CommitIntegrationTestSuite) TestCommitAtTimeChange() {
ts := e2e.New(suite.T(), false)
defer ts.Close()

ts.PrepareProjectAndBuildScript("ActiveState-CLI/Commit-Test-A", "7a1b416e-c17f-4d4a-9e27-cbad9e8f5655")
ts.PrepareProjectAndBuildScript("ActiveState-CLI/Commit-Test-A", "2ab50eba-4410-4be2-ba9d-c04ebeda640d")

proj, err := project.FromPath(ts.Dirs.Work)
suite.NoError(err, "Error loading project")
Expand All @@ -76,11 +76,11 @@ func (suite *CommitIntegrationTestSuite) TestCommitAtTimeChange() {
suite.Require().NoError(err) // verify validity

// Update top-level at_time variable.
dateTime := "2023-06-21T12:34:56Z"
dateTime := "2025-12-11T12:34:56Z"
buildScriptFile := filepath.Join(proj.Dir(), constants.BuildScriptFileName)
contents, err := fileutils.ReadFile(buildScriptFile)
suite.Require().NoError(err)
contents = bytes.Replace(contents, []byte("2023-06-22T21:56:10Z"), []byte(dateTime), 1)
contents = bytes.Replace(contents, []byte("2025-12-10T17:03:26Z"), []byte(dateTime), 1)
suite.Require().NoError(fileutils.WriteFile(buildScriptFile, contents))
suite.Require().Contains(string(fileutils.ReadFileUnsafe(filepath.Join(proj.Dir(), constants.BuildScriptFileName))), dateTime)

Expand Down Expand Up @@ -152,14 +152,16 @@ func (suite *CommitIntegrationTestSuite) TestCommitSkipValidation() {
suite.Require().NoError(fileutils.WriteFile(scriptPath, data))

cp := ts.Spawn("commit")
cp.Expect("solver_version in body should be")
cp.Expect("solver_version")
cp.Expect("should be")
cp.ExpectExitCode(1)

cp = ts.Spawn("commit", "--skip-validation")
cp.ExpectExitCode(0)

cp = ts.Spawn("refresh")
cp.Expect("solver_version in body should be")
cp.Expect("solver_version")
cp.Expect("should be")
cp.ExpectExitCode(1)
}

Expand Down
10 changes: 8 additions & 2 deletions test/integration/install_int_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package integration

import (
"path/filepath"
"runtime"
"strings"
"testing"

Expand Down Expand Up @@ -40,10 +41,15 @@ func (suite *InstallIntegrationTestSuite) TestInstallSuggest() {
cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true")
cp.ExpectExitCode(0)

cp = ts.Spawn("install", "djang")
package_name := "djang"
if runtime.GOOS == "linux" {
// For some reason, "djang" on Linux often fails to show suggestions.
package_name = "jinj"
}
cp = ts.Spawn("install", package_name)
cp.Expect("No results found", e2e.RuntimeSolvingTimeoutOpt)
cp.Expect("Did you mean")
cp.Expect("language/python/djang")
cp.Expect("language/python/" + package_name)
cp.ExpectExitCode(1)
}

Expand Down
6 changes: 4 additions & 2 deletions test/integration/package_int_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -679,12 +679,14 @@ func (suite *PackageIntegrationTestSuite) TestChangeSummary() {
cp.Expect("Successfully set")
cp.ExpectExitCode(0)

ts.PrepareProject("ActiveState-CLI/small-python", "5a1e49e5-8ceb-4a09-b605-ed334474855b")
ts.PrepareProject("ActiveState-CLI/small-python", "66f0259d-5d7a-48ce-a814-fd9db46c5ce6")

cp = ts.Spawn("install", "requests@2.31.0")
cp.Expect("Resolving Dependencies")
cp.Expect("Done")
cp.Expect("Installing requests@2.31.0 includes 4 direct dependencies")
cp.Expect("Installing")
cp.Expect("requests@2.31.0")
cp.Expect("includes 4 direct dependencies")
cp.Expect("├─ ")
cp.Expect("├─ ")
cp.Expect("├─ ")
Expand Down
5 changes: 3 additions & 2 deletions test/integration/platforms_int_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@ func (suite *PlatformsIntegrationTestSuite) TestPlatforms_listSimple() {
{"platforms"},
{"platforms", "search"},
}

for _, cmd := range cmds {
cp := ts.Spawn(cmd...)
expectations := []string{
"Linux",
"4.18.0",
"Windows",
"10",
"x86",
"64",
}
Expand Down
16 changes: 8 additions & 8 deletions test/integration/revert_int_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ func (suite *RevertIntegrationTestSuite) TestRevert() {
defer ts.Close()

namespace := "ActiveState-CLI/Revert"
ts.PrepareProject(namespace, "903bf49a-6719-47f0-ae70-450d69532ece")
ts.PrepareProject(namespace, "ca615135-ef95-4392-aff5-85b6c7132789")

// Revert the commit that added urllib3.
commitID := "1f4f4f7d-7883-400e-b2ad-a5803c018ecd"
commitID := "c44885ee-af0e-4f52-b8ef-63c56fe255c6"
cp := ts.Spawn("revert", commitID)
cp.Expect(fmt.Sprintf("Operating on project %s", namespace))
cp.Expect("You are about to revert the following commit:")
Expand All @@ -48,7 +48,7 @@ func (suite *RevertIntegrationTestSuite) TestRevert() {
cp = ts.Spawn("shell", "Revert")
cp.ExpectInput(e2e.RuntimeSourcingTimeoutOpt)
cp.SendLine("python3")
cp.Expect("3.9.15")
cp.Expect("3.11.12")
cp.SendLine("import urllib3")
cp.Expect("No module named 'urllib3'")
cp.SendLine("import argparse")
Expand All @@ -63,7 +63,7 @@ func (suite *RevertIntegrationTestSuite) TestRevertRemote() {
ts := e2e.New(suite.T(), false)
defer ts.Close()

ts.PrepareProject("ActiveState-CLI/Revert", "75ae9c67-df55-4a95-be6f-b7975e5bb523")
ts.PrepareProject("ActiveState-CLI/Revert", "ca615135-ef95-4392-aff5-85b6c7132789")

cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true")
cp.ExpectExitCode(0)
Expand Down Expand Up @@ -106,13 +106,13 @@ func (suite *RevertIntegrationTestSuite) TestRevertTo() {
defer ts.Close()

namespace := "ActiveState-CLI/Revert"
ts.PrepareProject(namespace, "903bf49a-6719-47f0-ae70-450d69532ece")
ts.PrepareProject(namespace, "ca615135-ef95-4392-aff5-85b6c7132789")

cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true")
cp.ExpectExitCode(0)

// Revert the commit that added urllib3.
commitID := "1f4f4f7d-7883-400e-b2ad-a5803c018ecd"
commitID := "c44885ee-af0e-4f52-b8ef-63c56fe255c6"
cp = ts.Spawn("revert", "--to", commitID)
cp.Expect(fmt.Sprintf("Operating on project %s", namespace))
cp.Expect("You are about to revert to the following commit:")
Expand Down Expand Up @@ -153,12 +153,12 @@ func (suite *RevertIntegrationTestSuite) TestJSON() {
ts := e2e.New(suite.T(), false)
defer ts.Close()

ts.PrepareProject("ActiveState-CLI/Revert", "903bf49a-6719-47f0-ae70-450d69532ece")
ts.PrepareProject("ActiveState-CLI/Revert", "ca615135-ef95-4392-aff5-85b6c7132789")

cp := ts.Spawn("config", "set", constants.AsyncRuntimeConfig, "true")
cp.ExpectExitCode(0)

cp = ts.Spawn("revert", "--to", "1f4f4f7d-7883-400e-b2ad-a5803c018ecd", "-o", "json")
cp = ts.Spawn("revert", "--to", "c44885ee-af0e-4f52-b8ef-63c56fe255c6", "-o", "json")
cp.Expect(`{"current_commit_id":`, e2e.RuntimeSourcingTimeoutOpt)
cp.ExpectExitCode(0)
AssertValidJSON(suite.T(), cp)
Expand Down
4 changes: 2 additions & 2 deletions test/integration/use_int_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,10 @@ func (suite *UseIntegrationTestSuite) TestReset() {

cfg, err := config.New()
suite.NoError(err)
rcfile, err := subshell.New(cfg).RcFile()
suite.NoError(err)
if runtime.GOOS != "windows" {
rcfile, err := subshell.New(cfg).RcFile()
fileutils.FileExists(rcfile)
suite.NoError(err)
suite.Contains(string(fileutils.ReadFileUnsafe(rcfile)), ts.Dirs.DefaultBin, "PATH does not have your project in it")
}

Expand Down
2 changes: 1 addition & 1 deletion version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.48.1-RC1
0.48.1-RC2
Loading