Skip to content

Commit

Permalink
state import with SBOMs should still update the commit.
Browse files Browse the repository at this point in the history
We expect the solve to fail, but we should still update the commit so the user can see what was added, even if the runtime is no longer viable.
  • Loading branch information
mitchell-as committed Jul 29, 2024
1 parent 16b5648 commit 9281598
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 2 deletions.
24 changes: 23 additions & 1 deletion internal/runners/packages/import.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package packages

import (
"errors"
"fmt"
"os"
"strings"

"github.com/ActiveState/cli/internal/constants"
"github.com/ActiveState/cli/internal/errs"
Expand All @@ -19,6 +21,7 @@ import (
"github.com/ActiveState/cli/pkg/buildscript"
"github.com/ActiveState/cli/pkg/localcommit"
"github.com/ActiveState/cli/pkg/platform/api"
"github.com/ActiveState/cli/pkg/platform/api/buildplanner/response"
"github.com/ActiveState/cli/pkg/platform/api/buildplanner/types"
"github.com/ActiveState/cli/pkg/platform/api/reqsimport"
"github.com/ActiveState/cli/pkg/platform/model"
Expand All @@ -29,6 +32,8 @@ const (
defaultImportFile = "requirements.txt"
)

var errImportSbomSolve = errs.New("failed to solve SBOM")

// Confirmer describes the behavior required to prompt a user for confirmation.
type Confirmer interface {
Confirm(title, msg string, defaultOpt *bool) (bool, error)
Expand Down Expand Up @@ -143,7 +148,24 @@ func (i *Import) Run(params *ImportRunParams) (rerr error) {
// Solve the runtime.
rtCommit, err := bp.FetchCommit(stagedCommitId, proj.Owner(), proj.Name(), nil)
if err != nil {
return errs.Wrap(err, "Failed to fetch build result for previous commit")
var buildplannerErr *response.BuildPlannerError
if errors.As(err, &buildplannerErr) {
// When importing CycloneDX and SPDX SBOMs, we put all packages in the 'private/<org>'
// namespace, which will fail to solve. That is expected. However, we still want to update the
// local commit so the user can see what was imported, even if the runtime is not viable.
for _, verr := range buildplannerErr.ValidationErrors {
if strings.Contains(verr, "non-existent namespace: private/") {
if err := localcommit.Set(proj.Dir(), stagedCommitId.String()); err != nil {
return locale.WrapError(err, "err_package_update_commit_id")
}
return errImportSbomSolve
}
}
}

if err != nil {
return errs.Wrap(err, "Failed to fetch build result for staged commit")
}
}

// Output change summary.
Expand Down
6 changes: 6 additions & 0 deletions internal/runners/packages/rationalize.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,11 @@ func rationalizeError(auth *authentication.Auth, err *error) {
locale.Tl("err_import_unauthenticated", "Could not import requirements into a private namespace because you are not authenticated. Please authenticate using '[ACTIONABLE]state auth[/RESET]' and try again."),
errs.SetInput(),
)

case errors.Is(*err, errImportSbomSolve):
*err = errs.WrapUserFacing(*err,
locale.Tl("err_import_sbom_solve", "Import finished, but your runtime could not be created because the SBOM's requirements do not exist on the Platform."),
errs.SetInput(),
)
}
}
8 changes: 7 additions & 1 deletion test/integration/import_int_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ func (suite *ImportIntegrationTestSuite) TestImportCycloneDx() {

ts.PrepareEmptyProject()

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

jsonSbom := filepath.Join(osutil.GetTestDataDir(), "import", "cyclonedx", "bom.json")
xmlSbom := filepath.Join(osutil.GetTestDataDir(), "import", "cyclonedx", "bom.xml")

Expand Down Expand Up @@ -193,9 +196,12 @@ func (suite *ImportIntegrationTestSuite) TestImportSpdx() {

ts.PrepareEmptyProject()

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

jsonSbom := filepath.Join(osutil.GetTestDataDir(), "import", "spdx", "appbomination.spdx.json")

cp := ts.Spawn("import", jsonSbom)
cp = ts.Spawn("import", jsonSbom)
cp.Expect("Creating commit")
cp.Expect("Done")
cp.ExpectNotExitCode(0) // solve should fail due to private namespace
Expand Down

0 comments on commit 9281598

Please sign in to comment.