Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transitioning to buildscript is handled explicitly #3199

Merged
merged 38 commits into from
Apr 2, 2024
Merged

Conversation

Naatan
Copy link
Member

@Naatan Naatan commented Mar 26, 2024

TaskDX-2619 Transitioning to buildscripts / build expressions is handled explicitly

This is addressing several things:

  • Buildscripts are created explicitly; either because the project config needs migrating, or by running state reset.
  • Project config now has a migration mechanic
  • Runtime will error out if buildscripts are opted in but no buildscripts exist; you'll get an error informing you to run state reset LOCAL
  • Runtime runbits were refactored to ensure this new buildscript error is properly propagated in all scenarios

@mitchell-as
Copy link
Contributor

mitchell-as commented Mar 29, 2024

If I opt into buildscripts and then attempt to checkout a project, it will immediately fail:

% state checkout ActiveState-CLI/Merge#447b8363-024c-4143-bf4e-c96989314fdf
Checking out project: ActiveState-CLI/Merge

█ Installing Runtime

 x Your project is missing its buildscript file, please run 'state reset LOCAL' to recreate it.

If I prepend ACTIVESTATE_CLI_DISABLE_RUNTIME=true to the checkout, it will checkout, but then attempting to do something with the runtime (e.g. state install requests) will fail with an unhelpful error message:

% state install requests
█ Installing Package

Operating on project ActiveState-CLI/Merge, located at /Users/me/tmp/Merge.

 • Searching for requests in the ActiveState Catalog ✔ Found
 • Creating commit ✔ Done
 • Resolving Dependencies x Failed
█ Something Went Wrong

 x Could not initialize runtime.

Apparently I need to run state reset LOCAL first. This is very awkward.

Copy link
Member

@MDrakos MDrakos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a large PR so I tried to provide some higher level feedback. Overall the migration implementation looks good to me and makes sense.

if err != nil {
return errs.Wrap(err, "Could not solve runtime")
}
if strings.ToLower(os.Getenv(constants.DisableRuntime)) != "true" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: It's unfortunate that we have to have this here. Currently, outside of tests, this environment variable is only checked in the runtime package.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah agreed, but I don't see a way to address this without significant refactoring, which is what we're already planning on, just not for this story.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fair, I didn't want to tag this as anything other than a nit because I know we have the refactor coming.

// If updating failed due to unidentified errors, and the user is not authenticated, add a tip suggesting that they authenticate as
// this may be a private project.
// Note since we cannot assert the actual error type we do not wrap this as user-facing, as we do not know what we're
// dealing with so the localized underlying errors are more appropriate.
case isUpdateErr && !auth.Authenticated():
case !auth.Authenticated(): // MUST BE LAST
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this is not asserting an error, it's decorating an unknown error. And all the other assertions are for asserting an error.

I've updated the code with a comment and some protection against accidental refactoring.

Note the original implementation was bugged:

https://github.com/ActiveState/cli/pull/3199/files/3c9e66d2268323d48391a6b19658bd20b4a7e327#diff-ad4a4ce35107eceb3ee56dfede324f0f7eb85af84005dbd6dc158f5681e58c92L28

It was ignoring errors if those non-error assertions were evaluated. We really should void using rationalizers to do anything that's not error assertion related.


const (
OptNone Opts = 1 << iota
OptMinimalUI
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be something that is set in the outputter or in some sort of output layer? From reading just this file I'm not sure what this means and why it's coupled with the order changing, at least in terms of options.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add comments. I have no intention of using this outside of this package, or even beyond the runtime refactor. This is effectively a temporary workaround to get around the increasingly lacking architecture.

err = runtime.RefreshRuntime(r.auth, r.out, r.analytics, r.project, commitID, true, target.TriggerReset, r.svcModel, r.cfg)
// Ensure the buildscript exists. Normally we should never do this, but reset is used for resetting from a corrupted
// state, so it is appropriate.
if r.cfg.GetBool(constants.OptinBuildscriptsConfig) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have we considered centralizing the check of this config option to the buildscript package? Similar to how the DisableRuntime environment variable has worked before. It looks like every use, at least in this PR is followed by a call out to that package.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not really the same thing, the runtime instance is still getting called regardless of the env var, it just behaves differently. In this case we're not doing anything with the buildscript outside of this one call. Add to that the fact that we have some commands like commit and eval that do not care about this config, and it just makes more sense to have it in the runner.

@@ -266,39 +282,51 @@ func (b *BuildPlanByProject) CommitID() (strfmt.UUID, error) {
}

type BuildPlanByCommit struct {
Commit *Commit `json:"commit"`
commit *Commit `json:"commit"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that by making this field private the encoding/json package will not be able to access it so marhsalling/unmarshalling may fail. Maybe that's changed but I remember getting caught by this before.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Urgh you're right, thanks for catching!

if project.ConfigVersion > ConfigVersion {
return nil, locale.NewInputError("err_projectfile_version_too_high")
}
updatedConfigVersion, errMigrate := migrator(project, ConfigVersion)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will lose this error if anything on line 483 fails. We may want to log it in that case if this could be valuable.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Perfect job for errs.Pack().

return &yamlField{field: field, value: value}
}

func (y *yamlField) Save(path string) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this feels low level enough to have a unit test.

# Conflicts:
#	internal/locale/locales/en-us.yaml
#	internal/runners/packages/list.go
#	internal/runners/swtch/switch.go
@Naatan Naatan requested a review from MDrakos April 2, 2024 21:51
MDrakos
MDrakos previously approved these changes Apr 2, 2024
Copy link
Member

@MDrakos MDrakos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! Just left a couple of minor comments, not meant to hold up the PR.

internal/runbits/runtime/rationalize.go Outdated Show resolved Hide resolved
Comment on lines 220 to 223
if _, ok := artifactsDone[m.ArtifactID]; ok {
multilog.Critical("buildlogstreamer sent duplicate ArtifactSucceededMessage for artifact %s", m.ArtifactID.String())
break
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this meant to be a part of another story?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, yeah.. I had run git reset, not sure why this is still in :\

@Naatan Naatan requested a review from MDrakos April 2, 2024 22:26
@Naatan Naatan merged commit 7ba7ef6 into version/0-44-0-RC1 Apr 2, 2024
4 of 6 checks passed
@Naatan Naatan deleted the DX-2619 branch April 2, 2024 22:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants