-
Notifications
You must be signed in to change notification settings - Fork 5.7k
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(Packaging): Consider absolute artifact paths (#8325) #8315
fix(Packaging): Consider absolute artifact paths (#8325) #8315
Conversation
Codecov Report
@@ Coverage Diff @@
## master #8315 +/- ##
==========================================
+ Coverage 87.29% 87.42% +0.13%
==========================================
Files 256 254 -2
Lines 9655 9615 -40
==========================================
- Hits 8428 8406 -22
+ Misses 1227 1209 -18
Continue to review full report at Codecov.
|
I spent a bunch of time trying to figure out how to run the prettier check but first it wasn't running after installing via npm as described at https://prettier.io/docs/en/install.html and then I hit various config file issues ¯_(ツ)_/¯ so gonna give up with that, sorry. The change is trivial, and I'm not at all opinionated about it, so hopefully if it looks like a helpful fix someone will be able to handle whatever formatting tweaks are necessary, or rewrite, or find a different approach etc. |
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.
@rib thanks for this PR, still this doesn't look related to #6752 (which looks as a result of issue in plugin which blindly assumes existence of function[].package
)
While softprops/serverless-rust#82 seems also an error in plugin which for some reason assigns absolute and not relative path to package.artifact
Framework intentionally expects a relative path, as relying on absolute paths doesn't make service portable.
:-( Please at least check the last comment I wrote for #6752 which explains in detail how I arrived at this change last night. Saying thanks "this doesn't look related to #6752" is kinda frustrating from the pov of someone that spent their evening debugging why I've not been able to deploy single functions for a while now (which is what that issue is about). The patch literally fixes the issue for me. It also feels like your bouncing back my own debugging work at me by telling me the cause of softprops/serverless-rust#82 which I posted yesterday and also suggested that it could be good for serverless-rust to set a relative path. I marked this as Addresses #6752 not Closes because I see that there are clearly multiple things causing the same issue (I wouldn't have known that before spending the time to debug and investigate exactly what the cause of the bug was) My initial impression was that it might be more robust to remove the assumption about relative paths considering that I didnt see any documentation that explicitly clarified that requirement and it seemed plausible that the exact same issue might just crop up again later if it was only addressed by changing the serverless-rust plugin. Sorry if I sound grumpy - I think I was caught off guard by how dismissive the last comment was. It sounds fine to me if serverless only wants to support relative artifact paths and change serverless-rust accordingly (service portability sounds like a good reason). Personally I think if you decide that then I think it might still be worth considering adding a check for absolute paths that at least shows a warning/error to avoid having this issue easily repeat itself in the future. |
@rib I've read it, and what you've experienced does not look related to original #6752 report, and I've explained why I think so.
I believe that issues should be fixed at the source, and not in whatever way that makes issue "gone" for given specific case. Here seems the problem is in a plugin which without a valid reason produces an absolute path (note it may trigger some other issues which we're not aware of)
That's a very good idea. We probably should add such validation inline, directly in logic, as my guess is that plugin sets this property dynamically at runtime, so validating that just by property schema will not work (?) |
I've filed #8325 to track the more specific issue I ended up hitting |
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.
While it's hard to find a good reason for absolute paths, after all there's no harm in supporting them, and current behavior where invalid path is produced is clearly wrong.
I've proposed on how to solve it more cleanly
packageFunction(functionName) { | ||
const functionObject = this.serverless.service.getFunction(functionName); | ||
const funcPackageConfig = functionObject.package || {}; | ||
|
||
// use the artifact in function config if provided | ||
if (funcPackageConfig.artifact) { | ||
const filePath = path.join(this.serverless.config.servicePath, funcPackageConfig.artifact); | ||
const filePath = this.absoluteArtifactPath(funcPackageConfig.artifact); |
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.
Let' simply just use path.resolve
instead of path.join
(that alone will ensure that absolute paths are respected)
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.
ah, yep this looks good to me. I don't work with node.js often and was initially surprised that path.join didn't work that way by default - more like python's path.join which would have discarded the first absolute path automatically.
ef758d1
to
904c2c1
Compare
Ah, so |
@rib Tests fail cause of issue in tests, and not that we've introduced a bug. They implied a non absolute So best way to follow would be to just update tests to mock As a side note, we configure all new tests with help of |
@rib what is the status of that? Do you think you can finish it? We'd love to have that in |
Hello @rib , thanks a lot for your contributions to this PR 🙇 We'd like to wrap it up in the coming days, so I hope you don't mind me taking over your work and applying the finishing changes. Please let me know if you'd still like to continue your work here. Once again, your help is much appreciated 🙇 |
Yep, that's no problem @pgrzesik, sorry I haven't had time to follow up on this. thanks! |
904c2c1
to
4e1d587
Compare
6ef14f4
to
212b412
Compare
this.serverless.config.servicePath, | ||
this.serverless.service.package.artifact | ||
); | ||
funcPackageConfig.artifact = filePath; | ||
functionObject.package = funcPackageConfig; |
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 change is a bit controversial as it's changed only because I needed a way to perform an assertion in tests for service-wide
scenario - do you think there's another way of doing it without introducing extra production code?
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.
Why exactly do we need it?
Technically in tests we should purely test the outcome, so either inspect generated artifact, or generated CF template
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.
Would you suggest to assert on Properties.Code.S3Key
on CF function resources instead here?
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.
Would you suggest to assert on Properties.Code.S3Key on CF function resources instead here?
As I think more of it, that will also not work, as we just blindly assign there basename of artifact. So fact that full path is broken won't be exposed.
If I understand correctly we're fixing here issue that happens during deployment, where for upload to S3 we try to reach wrong path.
In light of that probably best test is one that tests against sls deploy
and sls deploy function
commands and confirms that we attempt to upload expected content to S3.
I think we can construct it by mocking AWS SDK through awsRequestStubMap option, and by setting lastLifecycleHookName to avoid full deployment process.
e.g. we have test that does something similar here:
lastLifecycleHookName: 'aws:deploy:deploy:checkForChanges', |
As hint you may inspect what exactly lifecycle events are triggered in which order by running deployment with debug
branch (I've just ensured it's up to date with master). It logs all meta about that (we will put into core with regular debug logs after we have #1720 addressed)
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.
For sls deploy function
we're just passing artifact data to updateFunctionCode
, so I've went this route for these tests (ensuring that AWS API is called with correct content). As for sls deploy
, I believe it's not affected by this issue, but I'll try to come up with meaningful tests for that scenario as well
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.
I've adjusted the approach a bit as confirming on the content was a bit cumbersome in case of readStream, so I've decided to confirm that the stream is created based on proper path to artifact
212b412
to
88df226
Compare
88df226
to
e3bb77c
Compare
c35f779
to
943b75c
Compare
@medikoo Would you be able to take a second look whenever you got a chance? |
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.
@pgrzesik looks great! I have just few questions, please see my comments
}, | ||
}, | ||
}, | ||
}); | ||
}); | ||
it('should support `package.artifact`', () => { | ||
|
||
it.skip('should support `package.artifact`', () => { |
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.
Let's add TODO:
prefix to message
}); | ||
|
||
// One with CF template, one with function artifact and one with provided function artifact | ||
expect(s3UploadStub).to.be.calledThrice; |
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.
Do you think it's important to confirm on that (?) I guess there are some unrelated uploads involved there
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.
I wanted to differentiate this way between the two cases (for service-wide scenario there's one upload less), but it's not essential I think
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.
It looks as implementation detail, which may change without breaking functionality (e.g. in some other unrelated part we'll do S3 upload and it'll break tests here), so i wouldn't cover this.
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.
makes sense, removed 👍
absoluteArtifactFilePath = path.join(process.cwd(), 'newArtifact.zip'); | ||
await fs.promises.writeFile(absoluteArtifactFilePath, zipContent); |
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.
Maybe we can reuse artifact directly from a fixture (we may eventually copy it to a new path, assuming that we rely on filename to confirm that things works)
2a3f6cf
to
eaf74cf
Compare
eaf74cf
to
0b1992e
Compare
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 great! 👍
Closes: #8325
Addresses #6752
Would also close softprops/serverless-rust#82
Although it looks like there may be more than one trigger for issue #6752, this change addresses one case seen as a result of the serverless-rust plugin setting artifacts with an absolute path which wasn't considered by
lib/packageService.js
.An alternative fix might change serverless-rust to set a relative path, but this seems like a more general fix.