Skip to content

Commit

Permalink
Merge branch 'version/0-41-0-RC1' into green-upds_from_svc-DX-1984
Browse files Browse the repository at this point in the history
# Conflicts:
#	cmd/state-svc/internal/server/generated/generated.go
#	cmd/state/autoupdate.go
  • Loading branch information
Naatan committed Sep 18, 2023
2 parents fc08407 + 1715420 commit c260bb5
Show file tree
Hide file tree
Showing 66 changed files with 759 additions and 255 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ jobs:
fail-fast: false
runs-on: ${{ matrix.platform }}
env:
ACTIVESTATE_CI: true
ACTIVESTATE_CLI_DISABLE_RUNTIME: true
SHELL: bash
GITHUB_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down Expand Up @@ -388,6 +389,7 @@ jobs:
- os_specific
runs-on: ubuntu-20.04
env:
ACTIVESTATE_CI: true
ACTIVESTATE_CLI_DISABLE_RUNTIME: true
SHELL: bash
GITHUB_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/propagate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ jobs:
go-version:
- 1.20.x
env:
ACTIVESTATE_CI: true
ACTIVESTATE_CLI_DISABLE_RUNTIME: true
SHELL: bash
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ jobs:
go-version:
- 1.20.x
env:
ACTIVESTATE_CI: true
ACTIVESTATE_CLI_DISABLE_RUNTIME: true
SHELL: bash
GITHUB_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ jobs:
name: Target & Verify PR
runs-on: ubuntu-20.04
env:
ACTIVESTATE_CI: true
ACTIVESTATE_CLI_DISABLE_RUNTIME: true
SHELL: bash
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
16 changes: 16 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,22 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres
to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

### 0.40.1

### Added

* State tool will now warn users if its executables are deleted during
installation, indicating a false-positive action from antivirus software.

### Fixed

* Fixed auto updates not being run (if you are on an older version:
run `state update`).
* Fixed a rare parsing panic that would happen when running particularly complex
builds.
* Fixed race condition during artifact installation that could lead to errors
like "Could not unpack artifact .. file already exists".

### 0.40.0

### Added
Expand Down
44 changes: 21 additions & 23 deletions cmd/state-installer/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/ActiveState/cli/internal/analytics"
"github.com/ActiveState/cli/internal/analytics/client/sync"
anaConst "github.com/ActiveState/cli/internal/analytics/constants"
"github.com/ActiveState/cli/internal/captain"
"github.com/ActiveState/cli/internal/config"
"github.com/ActiveState/cli/internal/constants"
Expand All @@ -37,9 +38,6 @@ import (
"golang.org/x/crypto/ssh/terminal"
)

const AnalyticsCat = "installer"
const AnalyticsFunnelCat = "installer-funnel"

type Params struct {
sourceInstaller string
path string
Expand Down Expand Up @@ -125,8 +123,8 @@ func main() {
logging.Debug("Original Args: %v", os.Args)
logging.Debug("Processed Args: %v", processedArgs)

an = sync.New(cfg, nil, out)
an.Event(AnalyticsFunnelCat, "start")
an = sync.New(anaConst.SrcStateInstaller, cfg, nil, out)
an.Event(anaConst.CatInstallerFunnel, "start")

params := newParams()
cmd := captain.NewCommand(
Expand Down Expand Up @@ -193,30 +191,30 @@ func main() {
},
)

an.Event(AnalyticsFunnelCat, "pre-exec")
an.Event(anaConst.CatInstallerFunnel, "pre-exec")
err = cmd.Execute(processedArgs[1:])
if err != nil {
errors.ReportError(err, cmd, an)
if locale.IsInputError(err) {
an.EventWithLabel(AnalyticsCat, "input-error", errs.JoinMessage(err))
an.EventWithLabel(anaConst.CatInstaller, "input-error", errs.JoinMessage(err))
logging.Debug("Installer input error: " + errs.JoinMessage(err))
} else {
an.EventWithLabel(AnalyticsCat, "error", errs.JoinMessage(err))
an.EventWithLabel(anaConst.CatInstaller, "error", errs.JoinMessage(err))
multilog.Critical("Installer error: " + errs.JoinMessage(err))
}

an.EventWithLabel(AnalyticsFunnelCat, "fail", errs.JoinMessage(err))
an.EventWithLabel(anaConst.CatInstallerFunnel, "fail", errs.JoinMessage(err))
exitCode, err = errors.ParseUserFacing(err)
if err != nil {
out.Error(err)
}
} else {
an.Event(AnalyticsFunnelCat, "success")
an.Event(anaConst.CatInstallerFunnel, "success")
}
}

func execute(out output.Outputer, cfg *config.Instance, an analytics.Dispatcher, args []string, params *Params) error {
an.Event(AnalyticsFunnelCat, "exec")
an.Event(anaConst.CatInstallerFunnel, "exec")

if params.path == "" {
var err error
Expand Down Expand Up @@ -274,13 +272,13 @@ func execute(out output.Outputer, cfg *config.Instance, an analytics.Dispatcher,
if params.isUpdate {
route = "update"
}
an.Event(AnalyticsFunnelCat, route)
an.Event(anaConst.CatInstallerFunnel, route)

// Check if state tool already installed
if !params.isUpdate && !params.force && stateToolInstalled && !targetingSameBranch {
logging.Debug("Cancelling out because State Tool is already installed")
out.Print(fmt.Sprintf("State Tool Package Manager is already installed at [NOTICE]%s[/RESET]. To reinstall use the [ACTIONABLE]--force[/RESET] flag.", installPath))
an.Event(AnalyticsFunnelCat, "already-installed")
an.Event(anaConst.CatInstallerFunnel, "already-installed")
params.isUpdate = true
return postInstallEvents(out, cfg, an, params)
}
Expand All @@ -295,7 +293,7 @@ func execute(out output.Outputer, cfg *config.Instance, an analytics.Dispatcher,
// installOrUpdateFromLocalSource is invoked when we're performing an installation where the payload is already provided
func installOrUpdateFromLocalSource(out output.Outputer, cfg *config.Instance, an analytics.Dispatcher, payloadPath string, params *Params) error {
logging.Debug("Install from local source")
an.Event(AnalyticsFunnelCat, "local-source")
an.Event(anaConst.CatInstallerFunnel, "local-source")
if !params.isUpdate {
// install.sh or install.ps1 downloaded this installer and is running it.
out.Print(output.Title("Installing State Tool Package Manager"))
Expand Down Expand Up @@ -324,12 +322,12 @@ func installOrUpdateFromLocalSource(out output.Outputer, cfg *config.Instance, a
}

// Run installer
an.Event(AnalyticsFunnelCat, "pre-installer")
an.Event(anaConst.CatInstallerFunnel, "pre-installer")
if err := installer.Install(); err != nil {
out.Print("[ERROR]x Failed[/RESET]")
return err
}
an.Event(AnalyticsFunnelCat, "post-installer")
an.Event(anaConst.CatInstallerFunnel, "post-installer")
out.Print("[SUCCESS]✔ Done[/RESET]")

if !params.isUpdate {
Expand All @@ -342,7 +340,7 @@ func installOrUpdateFromLocalSource(out output.Outputer, cfg *config.Instance, a
}

func postInstallEvents(out output.Outputer, cfg *config.Instance, an analytics.Dispatcher, params *Params) error {
an.Event(AnalyticsFunnelCat, "post-install-events")
an.Event(anaConst.CatInstallerFunnel, "post-install-events")

installPath, err := resolveInstallPath(params.path)
if err != nil {
Expand All @@ -368,30 +366,30 @@ func postInstallEvents(out output.Outputer, cfg *config.Instance, an analytics.D
switch {
// Execute provided --command
case params.command != "":
an.Event(AnalyticsFunnelCat, "forward-command")
an.Event(anaConst.CatInstallerFunnel, "forward-command")

out.Print(fmt.Sprintf("\nRunning `[ACTIONABLE]%s[/RESET]`\n", params.command))
cmd, args := exeutils.DecodeCmd(params.command)
if _, _, err := exeutils.ExecuteAndPipeStd(cmd, args, envSlice(binPath)); err != nil {
an.EventWithLabel(AnalyticsFunnelCat, "forward-command-err", err.Error())
an.EventWithLabel(anaConst.CatInstallerFunnel, "forward-command-err", err.Error())
return errs.Silence(errs.Wrap(err, "Running provided command failed, error returned: %s", errs.JoinMessage(err)))
}
// Activate provided --activate Namespace
case params.activate.IsValid():
an.Event(AnalyticsFunnelCat, "forward-activate")
an.Event(anaConst.CatInstallerFunnel, "forward-activate")

out.Print(fmt.Sprintf("\nRunning `[ACTIONABLE]state activate %s[/RESET]`\n", params.activate.String()))
if _, _, err := exeutils.ExecuteAndPipeStd(stateExe, []string{"activate", params.activate.String()}, envSlice(binPath)); err != nil {
an.EventWithLabel(AnalyticsFunnelCat, "forward-activate-err", err.Error())
an.EventWithLabel(anaConst.CatInstallerFunnel, "forward-activate-err", err.Error())
return errs.Silence(errs.Wrap(err, "Could not activate %s, error returned: %s", params.activate.String(), errs.JoinMessage(err)))
}
// Activate provided --activate-default Namespace
case params.activateDefault.IsValid():
an.Event(AnalyticsFunnelCat, "forward-activate-default")
an.Event(anaConst.CatInstallerFunnel, "forward-activate-default")

out.Print(fmt.Sprintf("\nRunning `[ACTIONABLE]state activate --default %s[/RESET]`\n", params.activateDefault.String()))
if _, _, err := exeutils.ExecuteAndPipeStd(stateExe, []string{"activate", params.activateDefault.String(), "--default"}, envSlice(binPath)); err != nil {
an.EventWithLabel(AnalyticsFunnelCat, "forward-activate-default-err", err.Error())
an.EventWithLabel(anaConst.CatInstallerFunnel, "forward-activate-default-err", err.Error())
return errs.Silence(errs.Wrap(err, "Could not activate %s, error returned: %s", params.activateDefault.String(), errs.JoinMessage(err)))
}
case !params.isUpdate && terminal.IsTerminal(int(os.Stdin.Fd())) && os.Getenv(constants.InstallerNoSubshell) != "true" && os.Getenv("TERM") != "dumb":
Expand Down
3 changes: 2 additions & 1 deletion cmd/state-offline-installer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/ActiveState/cli/internal/analytics"
"github.com/ActiveState/cli/internal/analytics/client/sync"
anaConst "github.com/ActiveState/cli/internal/analytics/constants"
"github.com/ActiveState/cli/internal/captain"
"github.com/ActiveState/cli/internal/config"
"github.com/ActiveState/cli/internal/constants"
Expand Down Expand Up @@ -78,7 +79,7 @@ func main() {
return
}

an = sync.New(cfg, nil, out)
an = sync.New(anaConst.SrcOfflineInstaller, cfg, nil, out)

prime := primer.New(
nil, out, nil,
Expand Down
3 changes: 2 additions & 1 deletion cmd/state-offline-uninstaller/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/ActiveState/cli/internal/analytics"
"github.com/ActiveState/cli/internal/analytics/client/sync"
anaConst "github.com/ActiveState/cli/internal/analytics/constants"
"github.com/ActiveState/cli/internal/captain"
"github.com/ActiveState/cli/internal/config"
"github.com/ActiveState/cli/internal/constants"
Expand Down Expand Up @@ -78,7 +79,7 @@ func main() {
return
}

an = sync.New(cfg, nil, out)
an = sync.New(anaConst.SrcOfflineInstaller, cfg, nil, out)

prime := primer.New(
nil, out, nil,
Expand Down
3 changes: 2 additions & 1 deletion cmd/state-remote-installer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/ActiveState/cli/internal/analytics"
"github.com/ActiveState/cli/internal/analytics/client/sync"
anaConst "github.com/ActiveState/cli/internal/analytics/constants"
"github.com/ActiveState/cli/internal/captain"
"github.com/ActiveState/cli/internal/config"
"github.com/ActiveState/cli/internal/constants"
Expand Down Expand Up @@ -94,7 +95,7 @@ func main() {
return
}

an = sync.New(cfg, nil, out)
an = sync.New(anaConst.SrcStateRemoteInstaller, cfg, nil, out)

// Set up prompter
prompter := prompt.New(true, an)
Expand Down
2 changes: 1 addition & 1 deletion cmd/state-svc/autostart/autostart.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
var Options = autostart.Options{
Name: constants.SvcAppName,
LaunchFileName: constants.SvcLaunchFileName,
Args: []string{"start"},
Args: []string{"start", "--autostart"},
}

func RegisterConfigListener(cfg *config.Instance) error {
Expand Down
14 changes: 8 additions & 6 deletions cmd/state-svc/internal/resolver/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ func New(cfg *config.Instance, an *sync.Client, auth *authentication.Auth) (*Res

usageChecker := rtusage.NewChecker(cfg, auth)

anForClient := sync.New(cfg, auth, nil)
// Note: source does not matter here, as analytics sent via the resolver have a source
// (e.g. State Tool or Executor), and that source will be used.
anForClient := sync.New(anaConsts.SrcStateTool, cfg, auth, nil)
return &Resolver{
cfg,
msg,
Expand Down Expand Up @@ -184,10 +186,10 @@ func (r *Resolver) Projects(ctx context.Context) ([]*graph.Project, error) {
return projects, nil
}

func (r *Resolver) AnalyticsEvent(_ context.Context, category, action string, _label *string, dimensionsJson string) (*graph.AnalyticsEventResponse, error) {
func (r *Resolver) AnalyticsEvent(_ context.Context, category, action, source string, _label *string, dimensionsJson string) (*graph.AnalyticsEventResponse, error) {
defer func() { handlePanics(recover(), debug.Stack()) }()

logging.Debug("Analytics event resolver: %s - %s", category, action)
logging.Debug("Analytics event resolver: %s - %s (%s)", category, action, source)

label := ""
if _label != nil {
Expand All @@ -213,12 +215,12 @@ func (r *Resolver) AnalyticsEvent(_ context.Context, category, action string, _l
return nil
})

r.anForClient.EventWithLabel(category, action, label, dims)
r.anForClient.EventWithSourceAndLabel(category, action, source, label, dims)

return &graph.AnalyticsEventResponse{Sent: true}, nil
}

func (r *Resolver) ReportRuntimeUsage(_ context.Context, pid int, exec string, dimensionsJSON string) (*graph.ReportRuntimeUsageResponse, error) {
func (r *Resolver) ReportRuntimeUsage(_ context.Context, pid int, exec, source string, dimensionsJSON string) (*graph.ReportRuntimeUsageResponse, error) {
defer func() { handlePanics(recover(), debug.Stack()) }()

logging.Debug("Runtime usage resolver: %d - %s", pid, exec)
Expand All @@ -227,7 +229,7 @@ func (r *Resolver) ReportRuntimeUsage(_ context.Context, pid int, exec string, d
return &graph.ReportRuntimeUsageResponse{Received: false}, errs.Wrap(err, "Could not unmarshal")
}

r.rtwatch.Watch(pid, exec, dims)
r.rtwatch.Watch(pid, exec, source, dims)

return &graph.ReportRuntimeUsageResponse{Received: true}, nil
}
Expand Down
7 changes: 4 additions & 3 deletions cmd/state-svc/internal/rtwatcher/entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import (
)

type entry struct {
PID int `json:"pid"`
Exec string `json:"exec"`
Dims *dimensions.Values `json:"dims"`
PID int `json:"pid"`
Exec string `json:"exec"`
Source string `json:"source"`
Dims *dimensions.Values `json:"dims"`
}

func (e entry) IsRunning() (bool, error) {
Expand Down
8 changes: 4 additions & 4 deletions cmd/state-svc/internal/rtwatcher/watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type Watcher struct {
}

type analytics interface {
Event(category string, action string, dim ...*dimensions.Values)
EventWithSource(category, action, source string, dim ...*dimensions.Values)
}

func New(cfg *config.Instance, an analytics) *Watcher {
Expand Down Expand Up @@ -97,7 +97,7 @@ func (w *Watcher) check() {

func (w *Watcher) RecordUsage(e entry) {
logging.Debug("Recording usage of %s (%d)", e.Exec, e.PID)
w.an.Event(anaConst.CatRuntimeUsage, anaConst.ActRuntimeHeartbeat, e.Dims)
w.an.EventWithSource(anaConst.CatRuntimeUsage, anaConst.ActRuntimeHeartbeat, e.Source, e.Dims)
}

func (w *Watcher) Close() error {
Expand All @@ -116,10 +116,10 @@ func (w *Watcher) Close() error {
return nil
}

func (w *Watcher) Watch(pid int, exec string, dims *dimensions.Values) {
func (w *Watcher) Watch(pid int, exec, source string, dims *dimensions.Values) {
logging.Debug("Watching %s (%d)", exec, pid)
dims.Sequence = ptr.To(-1) // sequence is meaningless for heartbeat events
e := entry{pid, exec, dims}
e := entry{pid, exec, source, dims}
w.watching = append(w.watching, e)
go w.RecordUsage(e) // initial event
}
Loading

0 comments on commit c260bb5

Please sign in to comment.