Skip to content

Commit

Permalink
Merge branch 'version/0-42-0-RC1' into DX-2224
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchell-as committed Oct 25, 2023
2 parents be532ea + 0d01e1a commit 92da15e
Show file tree
Hide file tree
Showing 6 changed files with 225 additions and 19 deletions.
44 changes: 26 additions & 18 deletions internal/runners/initialize/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"path/filepath"
"strings"

"github.com/go-openapi/strfmt"

"github.com/ActiveState/cli/internal/analytics"
"github.com/ActiveState/cli/internal/constants"
"github.com/ActiveState/cli/internal/errs"
Expand Down Expand Up @@ -86,6 +88,7 @@ func inferLanguage(config projectfile.ConfigGetter) (string, string, bool) {
}

func (r *Initialize) Run(params *RunParams) (rerr error) {
defer rationalizeError(&rerr)
logging.Debug("Init: %s/%s %v", params.Namespace.Owner, params.Namespace.Project, params.Private)

if !r.auth.Authenticated() {
Expand Down Expand Up @@ -217,7 +220,29 @@ func (r *Initialize) Run(params *RunParams) (rerr error) {
return err
}

commitID, err := model.CommitInitial(model.HostPlatform, lang.Requirement(), version)
logging.Debug("Creating Platform project")

platformID, err := model.PlatformNameToPlatformID(model.HostPlatform)
if err != nil {
return errs.Wrap(err, "Unable to determine Platform ID from %s", model.HostPlatform)
}

timestamp, err := model.FetchLatestTimeStamp()
if err != nil {
return errs.Wrap(err, "Unable to fetch latest timestamp")
}

bp := model.NewBuildPlannerModel(r.auth)
commitID, err := bp.CreateProject(&model.CreateProjectParams{
Owner: namespace.Owner,
Project: namespace.Project,
PlatformID: strfmt.UUID(platformID),
Language: lang.Requirement(),
Version: version,
Private: params.Private,
Timestamp: *timestamp,
Description: locale.T("commit_message_add_initial"),
})
if err != nil {
return locale.WrapError(err, "err_init_commit", "Could not create initial commit")
}
Expand All @@ -233,23 +258,6 @@ func (r *Initialize) Run(params *RunParams) (rerr error) {
}
}

logging.Debug("Creating Platform project and pushing it")

platformProject, err := model.CreateEmptyProject(namespace.Owner, namespace.Project, params.Private)
if err != nil {
return locale.WrapInputError(err, "err_init_create_project", "Failed to create a Platform project at {{.V0}}.", namespace.String())
}

branch, err := model.DefaultBranchForProject(platformProject) // only one branch for newly created project
if err != nil {
return locale.NewInputError("err_no_default_branch")
}

err = model.UpdateProjectBranchCommitWithModel(platformProject, branch.Label, commitID)
if err != nil {
return locale.WrapError(err, "err_init_push", "Failed to push to the newly created Platform project at {{.V0}}", namespace.String())
}

err = runbits.RefreshRuntime(r.auth, r.out, r.analytics, proj, commitID, true, target.TriggerInit, r.svcModel)
if err != nil {
logging.Debug("Deleting remotely created project due to runtime setup error")
Expand Down
29 changes: 29 additions & 0 deletions internal/runners/initialize/rationalize.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package initialize

import (
"errors"

"github.com/ActiveState/cli/internal/errs"
"github.com/ActiveState/cli/internal/locale"
bpModel "github.com/ActiveState/cli/pkg/platform/api/buildplanner/model"
)

func rationalizeError(err *error) {
if err == nil {
return
}

pcErr := &bpModel.ProjectCreatedError{}
if !errors.As(*err, &pcErr) {
return
}
switch pcErr.Type {
case bpModel.AlreadyExistsErrorType:
*err = errs.NewUserFacing(locale.Tl("err_create_project_exists", "That project already exists."), errs.SetInput())
case bpModel.ForbiddenErrorType:
*err = errs.NewUserFacing(
locale.Tl("err_create_project_forbidden", "You do not have permission to create that project"),
errs.SetInput(),
errs.SetTips(locale.T("err_init_authenticated")))
}
}
25 changes: 25 additions & 0 deletions pkg/platform/api/buildplanner/model/buildplan.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,21 @@ func ProcessProjectError(project *Project, fallbackMessage string) error {
return errs.New(fallbackMessage)
}

type ProjectCreatedError struct {
Type string
Message string
}

func (p *ProjectCreatedError) Error() string { return p.Message }

func ProcessProjectCreatedError(pcErr *projectCreated, fallbackMessage string) error {
if pcErr.Type != "" {
// These will be handled individually per type as user-facing errors in DX-2300.
return &ProjectCreatedError{pcErr.Type, pcErr.Message}
}
return errs.New(fallbackMessage)
}

type BuildExpression struct {
Type string `json:"__typename"`
Commit *Commit `json:"commit"`
Expand All @@ -355,6 +370,16 @@ type StageCommitResult struct {
Commit *Commit `json:"stageCommit"`
}

type projectCreated struct {
Type string `json:"__typename"`
Commit *Commit `json:"commit"`
*Error
}

type CreateProjectResult struct {
ProjectCreated *projectCreated `json:"createProject"`
}

// Error contains an error message.
type Error struct {
Message string `json:"message"`
Expand Down
57 changes: 57 additions & 0 deletions pkg/platform/api/buildplanner/request/createproject.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package request

import "github.com/ActiveState/cli/pkg/platform/runtime/buildexpression"

func CreateProject(owner, project string, private bool, expr *buildexpression.BuildExpression, description string) *createProject {
return &createProject{map[string]interface{}{
"organization": owner,
"project": project,
"private": private,
"expr": expr,
"description": description,
}}
}

type createProject struct {
vars map[string]interface{}
}

func (c *createProject) Query() string {
return `
mutation ($organization: String!, $project: String!, $private: Boolean!, $expr: BuildExpr!, $description: String!) {
createProject(input:{organization:$organization, project:$project, private:$private, expr:$expr, description:$description}) {
... on ProjectCreated {
__typename
commit {
__typename
commitId
}
}
... on AlreadyExists {
__typename
message
}
... on NotFound {
__typename
message
}
... on ParseError {
__typename
message
path
}
... on ValidationError {
__typename
message
}
... on Forbidden {
__typename
message
}
}
}`
}

func (c *createProject) Vars() map[string]interface{} {
return c.vars
}
60 changes: 60 additions & 0 deletions pkg/platform/model/buildplanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,66 @@ func (bp *BuildPlanner) GetBuildExpression(owner, project, commitID string) (*bu
return expression, nil
}

type CreateProjectParams struct {
Owner string
Project string
PlatformID strfmt.UUID
Language string
Version string
Private bool
Timestamp strfmt.DateTime
Description string
}

func (bp *BuildPlanner) CreateProject(params *CreateProjectParams) (strfmt.UUID, error) {
logging.Debug("CreateProject, owner: %s, project: %s, language: %s, version: %s", params.Owner, params.Project, params.Language, params.Version)

// Construct an initial buildexpression for the new project.
expr, err := buildexpression.NewEmpty()
if err != nil {
return "", errs.Wrap(err, "Unable to create initial buildexpression")
}

// Add the platform.
expr.UpdatePlatform(model.OperationAdded, params.PlatformID)

// Create a requirement for the given language and version.
versionRequirements, err := VersionStringToRequirements(params.Version)
if err != nil {
return "", errs.Wrap(err, "Unable to read version")
}
expr.UpdateRequirement(model.OperationAdded, bpModel.Requirement{
Name: params.Language,
Namespace: "language", // TODO: make this a constant DX-1738
VersionRequirement: versionRequirements,
})

// Add the timestamp.
expr.UpdateTimestamp(params.Timestamp)

// Create the project.
request := request.CreateProject(params.Owner, params.Project, params.Private, expr, params.Description)
resp := &bpModel.CreateProjectResult{}
err = bp.client.Run(request, resp)
if err != nil {
return "", processBuildPlannerError(err, "Failed to create project")
}

if resp.ProjectCreated == nil {
return "", errs.New("ProjectCreated is nil")
}

if bpModel.IsErrorResponse(resp.ProjectCreated.Type) {
return "", bpModel.ProcessProjectCreatedError(resp.ProjectCreated, "Could not create project")
}

if resp.ProjectCreated.Commit == nil {
return "", errs.New("ProjectCreated.Commit is nil")
}

return resp.ProjectCreated.Commit.CommitID, nil
}

// processBuildPlannerError will check for special error types that should be
// handled differently. If no special error type is found, the fallback message
// will be used.
Expand Down
29 changes: 28 additions & 1 deletion pkg/platform/runtime/buildexpression/buildexpression.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ type In struct {
Name *string
}

// NewBuildExpression creates a BuildExpression from a JSON byte array.
// New creates a BuildExpression from a JSON byte array.
// The JSON must be a valid BuildExpression in the following format:
//
// {
Expand Down Expand Up @@ -171,6 +171,33 @@ func New(data []byte) (*BuildExpression, error) {
return expr, nil
}

// NewEmpty creates a minimal, empty buildexpression.
func NewEmpty() (*BuildExpression, error) {
// At this time, there is no way to ask the Platform for an empty buildexpression, so build one
// manually.
expr, err := New([]byte(`
{
"let": {
"runtime": {
"solve_legacy": {
"at_time": "",
"build_flags": [],
"camel_flags": [],
"platforms": [],
"requirements": [],
"solver_version": null
}
},
"in": "$runtime"
}
}
`))
if err != nil {
return nil, errs.Wrap(err, "Unable to create initial buildexpression")
}
return expr, nil
}

func newLet(path []string, m map[string]interface{}) (*Let, error) {
path = append(path, ctxLet)
defer func() {
Expand Down

0 comments on commit 92da15e

Please sign in to comment.