-
Notifications
You must be signed in to change notification settings - Fork 130
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
Functions 7452: Bundling and uploading wasm file to GCS for function extension #4445
Conversation
Thanks for your contribution! Depending on what you are working on, you may want to request a review from a Shopify team:
|
e0c4923
to
8c1179a
Compare
} | ||
|
||
await this.build(options) | ||
|
||
if (this.isFunctionExtension) { | ||
await copyFile(this.outputPath, joinPath(bundleDirectory, extensionId, 'index.wasm')) |
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.
Copying the wasm file generated from the function's dist
directory to the bundleDirectory for it to get zipped and uploaded later.
@@ -243,7 +243,7 @@ describe('deploy', () => { | |||
expect(updateAppIdentifiers).toHaveBeenCalledOnce() | |||
}) | |||
|
|||
test('uploads the extension bundle with 1 function', async () => { | |||
test('uploads the extension bundle with 1 function extension', async () => { |
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.
Keeping the test names consistent.
@@ -290,7 +290,7 @@ describe('deploy', () => { | |||
], | |||
developerPlatformClient, | |||
extensionIds: {}, | |||
bundlePath: undefined, | |||
bundlePath: expect.stringMatching(/bundle.zip$/), |
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.
Bundle path now has a zip file for functions' assets.
04ce5e5
to
c5a48a8
Compare
Coverage report
Show files with reduced coverage 🔻
Test suite run success1943 tests passing in 876 suites. Report generated by 🧪jest coverage report action from 6834807 |
We detected some changes at either packages/*/src or packages/cli-kit/assets/cli-ruby/** and there are no updates in the .changeset. |
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 is looking great! My comments are mostly around Isaac's concerns 😄
a53dfe6
to
16a1fca
Compare
if (extension.isJavaScript) { | ||
await runCommandOrBuildJSFunction(extension, options) | ||
} else { | ||
await buildOtherFunction(extension, options) | ||
} | ||
if (fileExistsSync(extension.outputPath)) { |
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.
Had to add this if condition because I see there are tests like succeeds when is a JS function and build command is not present
so I assume thats the intention.
16a1fca
to
c1c12ea
Compare
@@ -141,11 +142,18 @@ export async function buildFunctionExtension( | |||
} | |||
|
|||
try { | |||
const bundlePath = joinPath(extension.outputPath.split('/').slice(0, -2).join('/'), 'index.wasm') | |||
extension.outputPath = joinPath(extension.directory, joinPath('dist', 'function.wasm')) |
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 little dance avoids isFunctionExtension?
in build
.
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 mind explaining why this step is necessary? I'm not totally following 🤔
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.
Yes, outputPath
ends up becoming <bundlepath>/dist/something.js
and since <bundlepath>/dist/
does not exists it complains No such file or directory
(remember that bundlePath is a /tmp
directory). So, I essentially set it to the valid path that exists which is <extension directory>/dist
.
4c9da9a
to
fc66510
Compare
@@ -141,11 +142,18 @@ export async function buildFunctionExtension( | |||
} | |||
|
|||
try { | |||
const bundlePath = joinPath(extension.outputPath.split('/').slice(0, -2).join('/'), 'index.wasm') | |||
extension.outputPath = joinPath(extension.directory, joinPath('dist', 'function.wasm')) |
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 mind explaining why this step is necessary? I'm not totally following 🤔
async deployConfig({ | ||
apiKey, | ||
developerPlatformClient, | ||
appConfiguration, | ||
}: ExtensionDeployConfigOptions): Promise<{[key: string]: unknown} | undefined> { | ||
if (this.isFunctionExtension) return this.functionDeployConfig({apiKey, developerPlatformClient, appConfiguration}) | ||
return this.commonDeployConfig(apiKey, appConfiguration) |
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 is looking good!!!
I'll ask for one more change, since now deployConfig
is basically doing nothing and just calling commonDeployConfig
can we unify both?
Have a single deployConfig
that does whatever commonDeployConfig
does.
And update all calls to commonDeployConfig
to call deployConfig
instead. Should be straightforward :)
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.
Indeed, thanks for catching that, it was easy to fix!
386b12b
to
4c6bf01
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.
I didn't 🎩 but overall the code LGTM! Nice work!
const base64Contents = await readFile(extension.outputPath, {encoding: 'base64'}) | ||
await touchFile(bundlePath) | ||
await writeFile(bundlePath, base64Contents) |
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.
Could we use copyFile
here instead of reading and writing?
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 did have copyFile
here before but I need it to be in base64
format inside the bundlePath
because code in core expects this to be base64
formatted, so copyFIle
which copies file as is doesn't work here.
4c6bf01
to
43b671e
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.
Awesome work @saga-dasgupta, thank you so much for all the extra clean up 🙇
47477ba
to
bb7b4f0
Compare
bb7b4f0
to
6834807
Compare
Issue: https://github.com/Shopify/script-service/issues/7452
WHY are these changes introduced?
To have a consistent way of uploading and obtaining extension data is core using the App Module Framework.
WHAT is this pull request doing?
This PR adds the "bundling" feature to functions and sets the output path for compilation to the bundle directory to ensure the wasm file generated is zipped and uploaded to GCS like every other extension.
The deployment plan is:
This version of CLI goes out which bundles the wasm file and uploads it (existing wasm blob upload stays in place).
Then on Core's side we verify we are able to obtain the wasm content and upload it to our runtime-engine bucket. Then we come back here and delete the uploadWasmBlob path and in core we throw an error when we fail to upload. TLDR: existing upload path stays in place till we can verify new path works.
How to test your changes?
Tophat this normally from your local computer since core changes are out. Run cli for dev and deploy both for an app with functions
Post-release steps
Measuring impact
How do we know this change was effective? Please choose one:
Checklist