-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feat: automate and publish prebuilt binaries #1083
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
Conversation
jmillan
left a comment
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 really nice!
npm-scripts.js
Outdated
| function extractRemoteTar(tarUrl, cwd) | ||
| { | ||
| const tar = require('tar'); | ||
| const axios = require('axios'); |
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.
Can we avoid this dependency just for making a single HTTP request?
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'm unaware of a simple, dependency free way to make http requests. fetch in node is experimental in 17.5 and still hasn't entered stability in 19.
Do you know of a way? (Simple being the key, I can use node:http but it would add a lot of 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.
node-fetch is 107KB while axios is 1.74MB.
I think the former is more than enough for the needed usage.
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.
Done! Swapped for node-fetch. Note that node-fetch >= 3 requires ESM, so I used node-fetch@2
|
Actually we already rejected a similar PR in the past and I would like to re-check the reasons why we did it. Let's please put this PR on hold for a while until we check that. |
|
Previously you'd rejected issues I'd created b/c you didn't want to maintain building the binaries and thought letting someone else create the binaries for you would be easier, which it obviously is. I think this introduces security risks though (Eg, how does an installer know that the binaries in the npm package aren't malicious if they don't come from the authors of the project?). Since the previous recommendation was "Put it in a separate page" I did that, as it's been working for a while, I figured I'd at least make the PR and see if your mind had changed, otherwise I'll keep maintaining my fork with this branch while I'm using this project. |
Co-authored-by: José Luis Millán <jmillan@aliax.net>
|
I see, thanks. Changes make sense and look great. Let's please have some days before we fully review and merge this PR. |
|
Easy question for now: how to prevent "npm ci" in my mediasoup local repo from downloading the binary instead of locally building it? If you call "make clean" in worker folder in your local fork and then run "npm run release:check", does it build the worker or does it fetch it from GH? It must do the former. |
|
|
.gitignore
Outdated
|
|
||
| ## Worker. | ||
| /worker/out | ||
| out/ |
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 this change? Why was worker/out worse? INMHO it makes sense that worker binary is located in worker/ folder. Do I miss something?
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 needed a place to download the prebuilds to, I wanted them to be different than worker/out so we wouldn't accidentally start taring tarballs, so I put them in repo-root/out. the binary is still in worker/out.
repo-root/out is fairly arbitrary, I was guessing what you'd prefer based on patterns in the repo, do you have thoughts on a different location for that?
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 would love worker/prebuilds/ and of course gitignore it.
| { | ||
| buildWorker(); | ||
|
|
||
| if (!process.env.MEDIASOUP_LOCAL_DEV) |
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.
We should not remove this condition. If MEDIASOUP_LOCAL_DEV env is given we should neither download binary from GH nor building it locally. Here in this PR we are downloading the binary from GH anyway.
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'm going to update the PR to do what you described in this comment, as the logic is simpler and the result should be faster. (If MEDIASOUP_LOCAL_DEV clean worker, else, attempt to download, if that fails, build it.
However, I think the current implementation if MEDIASOUP_LOCAL_DEV is set, builds the worker then removes it? Is that intentional?
Let me know if I misinterpreted your feedback.
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.
If MEDIASOUP_LOCAL_DEV is given then it should not download the prebuilt binary, it should build it locally and should NOT delete built artifacts after it. It's basically for local development for not having to build everything when running make in worker folder.
However my comment was wrong (the above is correct). I meant another variable that is... I don't remember but you can see it in Worker.ts. If given, install or postinstall script should neither download binary nor try to build local one. This is for people that want to run mediasoup with a binary compiled by themselves in some path (given in that env). Hope it's clear now.
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.
Ok, I meant MEDIASOUP_WORKER_BIN which is used in lines below.
npm-scripts.js
Outdated
| } | ||
| } | ||
|
|
||
| function createTar(files, dest) |
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.
Shouldn't this function be async? Shouldn't the caller awaits for it to complete? Same concern for functions below.
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.
Most are, just not explicitly. I went through and explicitly called them out as async or converted them to return promises if they didn't already.
npm-scripts.js
Outdated
| { | ||
| cleanWorker(); | ||
| } | ||
| console.error('Failed to download prebuilt binary, building instead', error.message); |
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.
Those logs don't conform to the syntax of other console logs in same file. Also, why are you using then and catch instead of try/catch with await in the try block? We strongly promote that.
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.
Old habits I guess. This is the first instance of async/await in this file and top level await was added unflagged in node 14.8. Your package.json says you support >=16 so that change should be fine. I'll make the change.
Note that it will explicitly break earlier versions of node, which I just confirmed are out of maintenance, so probably fine.
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.
Yup :)
BTW I've pulled your branch and I'm some cosmetic changes so I'll ask you later to cherry-pick them in your branch. So let me please convert those to await syntax.
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.
Hmm. Today I learned something new about top level await (honestly never attempted it before). In order to convert the syntax to async/await I'd need to convert the whole file into ESM instead of CJS.
So, renamed to npm-scripts.mjs and swap the require for import statements.
I'm happy to do so, but I wanted to check with you before I rewrite a lot.
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.
Actually I'm making many changes into the file, wondering if you'd mind to wait for me to finish
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.
👍 Sorry, pausing for a few hours, I'll circle back around in the afternoon after meetings and your changes are done.
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.
Thanks a lot. I'll ping you here when I'm done.
|
Correct me if I'm wrong but we don't really need those 'prebuild:download' and 'prebuild:unpackage' tasks at all, right? I'm trying to simplify things. |
|
We don't, I added them for development of the script itself, so they could be removed. |
|
Commit done, but I had to fork your fork: c1f08d8 So if you like, can you NOTE: I'll be back tomorrow. |
|
@barlock I am working in a forked branch/PR here: #1087 There are two concerns I have:
I'll try to do these things later in my branch. |
This PR untar's the downloaded worker to
Great! How would you like me to help with those changes? Would you prefer me to make PRs against that PR or cherry-pick into this one? I believe I also gave you should have the ability to make changes on this branch as a maintainer? While pulling in changes I'm testing the end-to-end CD flow in my fork that I've been using. GHA are failing in your changes due to Alternatively we could just add a |
|
If you don't mind I'm doing too many changes already in my branch. Not sure why I couldn't push to yours. I use Would you mind waiting for me to finish my ongoing stuff and then we discuss pending things? Regarding use of |
|
NOTE: All credits will be for you in CHANGELOG and announcement and so on. |
|
👍 I'll keep checking out your branch and ill wait for you to let me know how and when I can pitch in. Thanks for the credit, 😁 I'm more interested in seeing the change go through and I'm happy it's getting added. |
|
I'm almost done in #1087. Let me please close this one. |
|
PR is done and all pending stuff done: #1087 |
This PR automates and builds prebuilt binaries that get downloaded as a post-install step instead of building.
Typically builds on CI take me 6 minutes which over time adds up pretty significantly (especially when you consider that adding up to about 4 years of total community compute time per week of installs of this package 😱). This also cuts the build requirements for windows machines.
I've been using this branch in a fork to create prebuilds for myself since Dec and it's been working great.
The only change to typical process that you would need to make after this change would be that instead of creating just tags, you would need to create a release with the same name as the tag. You can see examples in my fork.