Skip to content
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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

saga-dasgupta
Copy link
Contributor

@saga-dasgupta saga-dasgupta commented Sep 12, 2024

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?

  • Checkout my branch and set up dev GCS bucket credentials for spin instructions here.
  • Set up spin credentials instructions here.
  • Create a functions app in your spin instance.
  • Checkout my core branch functions.move_wasm_file_to_permanent_bucket on your spin instance.
  • To remove any false positives replace this upload wasm line in cli with a random UUID.
  • Run pnpm run shopify app deploy --path [path to your app] from cli
  • Go to either cli or core logs to obtain the UUID.wasm type name of the file uploaded to the staging bucket. It should match your UUID in the previous step.
  • Find the uploaded file here.
  • Run pnpm run shopify app dev --path [path to your functions app] from cli and ensure the wasm file is present in the staging bucket.

Post-release steps

Measuring impact

How do we know this change was effective? Please choose one:

  • n/a - this doesn't need measurement, e.g. a linting rule or a bug-fix
  • Existing analytics will cater for this addition
  • PR includes analytics changes to measure impact

Checklist

  • I've considered possible cross-platform impacts (Mac, Linux, Windows)
  • I've considered possible documentation changes

Copy link
Contributor

Thanks for your contribution!

Depending on what you are working on, you may want to request a review from a Shopify team:

  • Themes: @shopify/advanced-edits
  • UI extensions: @shopify/ui-extensions-cli
    • Checkout UI extensions: @shopify/checkout-ui-extensions-api-stewardship
  • Hydrogen: @shopify/hydrogen
  • Other: @shopify/app-inner-loop

@saga-dasgupta saga-dasgupta force-pushed the functions_7452.gcs_upload_solution branch 3 times, most recently from e0c4923 to 8c1179a Compare September 13, 2024 16:26
}

await this.build(options)

if (this.isFunctionExtension) {
await copyFile(this.outputPath, joinPath(bundleDirectory, extensionId, 'index.wasm'))
Copy link
Contributor Author

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 () => {
Copy link
Contributor Author

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$/),
Copy link
Contributor Author

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.

@saga-dasgupta saga-dasgupta force-pushed the functions_7452.gcs_upload_solution branch 3 times, most recently from ad36761 to 04ce5e5 Compare September 17, 2024 16:22
@saga-dasgupta saga-dasgupta force-pushed the functions_7452.gcs_upload_solution branch from 04ce5e5 to c5a48a8 Compare September 17, 2024 16:26
Copy link
Contributor

github-actions bot commented Sep 17, 2024

Coverage report

St.
Category Percentage Covered / Total
🟡 Statements
73% (-0.02% 🔻)
8396/11501
🟡 Branches
69.58% (+0.06% 🔼)
4095/5885
🟡 Functions
71.75% (-0.07% 🔻)
2179/3037
🟡 Lines
73.35% (-0.02% 🔻)
7945/10832
Show files with reduced coverage 🔻
St.
File Statements Branches Functions Lines
🔴
... / marketing_activity.ts
25% (-75% 🔻)
100%
0% (-100% 🔻)
25% (-75% 🔻)
🟢
... / context.ts
91.67% (-0.03% 🔻)
87.28% 88.57%
92.62% (-0.03% 🔻)
🔴
... / extension.ts
54.55% (-0.72% 🔻)
50% 57.14%
55.81% (-0.94% 🔻)

Test suite run success

1891 tests passing in 857 suites.

Report generated by 🧪jest coverage report action from c1c12ea

@saga-dasgupta saga-dasgupta marked this pull request as ready for review September 17, 2024 16:32
Copy link
Contributor

We detected some changes at either packages/*/src or packages/cli-kit/assets/cli-ruby/** and there are no updates in the .changeset.
If the changes are user-facing, run "pnpm changeset add" to track your changes and include them in the next release CHANGELOG.

Copy link
Contributor

@andrewhassan andrewhassan left a 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 😄

@saga-dasgupta saga-dasgupta force-pushed the functions_7452.gcs_upload_solution branch 2 times, most recently from a53dfe6 to 16a1fca Compare September 20, 2024 20:27
if (extension.isJavaScript) {
await runCommandOrBuildJSFunction(extension, options)
} else {
await buildOtherFunction(extension, options)
}
if (fileExistsSync(extension.outputPath)) {
Copy link
Contributor Author

@saga-dasgupta saga-dasgupta Sep 20, 2024

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.

@saga-dasgupta saga-dasgupta force-pushed the functions_7452.gcs_upload_solution branch from 16a1fca to c1c12ea Compare September 20, 2024 20:40
@@ -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'))
Copy link
Contributor Author

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.

...config,
serialized_script: encodedFile,
}),
config: JSON.stringify(draftableConfig),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean we can remove the custom wasm update then? or are we waiting until this is released and used for a bit?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the latter!

@@ -107,4 +107,35 @@ describe('bundleAndBuildExtensions', () => {
await expect(file.fileExists(bundlePath)).resolves.toBeTruthy()
})
})

test('creates a zip file with wasm file in it for a function extension', async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are not really testing that the zip file includes a wasm file no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I really tried to unzip it and assert on the contents but would need to install some libraries for unzipping so I let it be. I did do end to end testing so I think just asserting a zip got generated here is sufficient.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is a good way to unzip files in cli? I didn't find any prior art for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Decided to remove reference to wasm file in the test title.

if (fileExistsSync(extension.outputPath)) {
const base64Contents = await readFile(extension.outputPath, {encoding: 'base64'})
await touchFile(bundlePath)
await writeFile(bundlePath, base64Contents)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tested if you need the touchFile line or is enough with writeFile? (I don't think writeFile needs the file to exist, but I might be wrong)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do, it was complaining no such file or directory exists without it so I had to add it.

@saga-dasgupta saga-dasgupta force-pushed the functions_7452.gcs_upload_solution branch from c1c12ea to 4c9da9a Compare September 23, 2024 17:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants