-
Notifications
You must be signed in to change notification settings - Fork 13
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
Fix SBOM nightly failures #3449
Conversation
MDrakos
commented
Aug 15, 2024
•
edited by github-actions
bot
Loading
edited by github-actions
bot
DX-3008 Nightly failure: CycloneDX and SPDX SBOM imports do not create commits |
Attempting to introduce an error case to the existing |
// StageCommitWithoutBuild stages a commit but does not request the corresponding build plan or | ||
// build expression. This is useful when we want to stage a commit but we know that the commit may | ||
// not solve successfully. This funciton should be used sparingly as requesting a build after calling | ||
// this function will result in excess solves. | ||
func (b *BuildPlanner) StageCommitWithoutBuild(params StageCommitParams) (strfmt.UUID, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels a little weird. It seems the issue is that the error we run into otherwise comes from some place that happens after we go beyond the "planned" stage of a build. So in effect what we are doing here is not avoiding buildscripts or buildplans so much as we're avoiding any state beyond "planned".
My problem with this is that it's very implicit behaviour. We basically expect the API to ALWAYS respond with "planned" at this stage, which may very well be true but that feels like a shaky contract to rely on.
I think what we need here is to do a normal stage commit, but to ensure that we receive a commit back regardless of whether it succeeded, so we can choose what to do with the result. Is that currently not happening with the StageCommit()
function?
Basically I'm saying we should always return the commit here:
return nil, errs.Wrap(err, "failed to poll build plan") |
Then consuming code (in this case the import runner) sees an error occurs, and it will error out but not before saving the commit, provided it is non-empty (meaning the error did not stop the commit from happening).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case the status of the build isn't planned, it outright failed. The reason I added this function is because the caller knowingly wants to disregard the build and just take the staged commit regardless.
Here is an example of the response we are getting from the API in this case:
{
"data": {
"stageCommit": {
"__typename": "Commit",
"expr": {
...
},
"commitId": "02a1fa15-90fd-44dc-9a5f-25918b8753ea",
"build": {
"__typename": "PlanningError",
"message": "Failed to create build plan",
"subErrors": [
{
"__typename": "GenericSolveError",
"path": ".solve_legacy",
"message": "The requested requirements refer to 1 non-existent namespace: private/ActiveState-CLI",
"isTransient": true,
"validationErrors": []
}
]
}
}
}
}
I would prefer to avoid using a return value when there is an error but that is just a preference. If you want to go that route we would have to return a partial Commit
object here:
return nil, response.ProcessBuildError(resp.Commit.Build, "Could not process error response from stage commit") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the API in this case still return the commit, or does it just return the error?
if it’s not planned and outright failed then I don’t understand how the new stagecommit function differs? Sounds like either variant would run into the same error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, the commit is returned which contains the commit ID and the build. The failure is in the build, which this function doesn't inspect because it only wants to return the staged commit ID.
We are reverting to the old way of using StageCommit
for import
as we want to update the project's local commit ID regardless of any build failures. In the case of CycloneDX and SPDX we are expecting this command to fail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By introducing the new function we're duplicating logic that will need to be maintained. And it's all to avoid an error being returned, which at that point isn't much different from ignoring the error, except that my suggestion has us explicitly ignoring it and the current solution implicitly avoids it.
I would prefer we go with the approach I described; do not introduce a new StageCommit function, instead always update the commit even if StageCommit()
returns an error (provided it did return a commit, of course).
Note that returning a result alongside an error and interpreting it is still idiomatic. It's about giving the full information to the consuming code to let it decide how to handle this scenario. I tried to find links explaining this pattern, but can't find anything explicitly touching on this subject. That said you can find plenty of examples of it in Go's standard library, eg. os.Read()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! I'm not sure how we're gonna resolve the commit/solve spinner conflict, but that's another story 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hit wrong button