Fork me on GitHub
#nbb
<
2022-06-28
>
borkdude08:06:07

So, about writing Github Actions with nbb: You can use it to write a Github Action (`action.yml`). But Github Actions wants you to put your dependencies into your repo, which is ugly, but apparently Github itself doesn't care about that. So what people do a lot is use a bundler/minifier/tree-shaker and put their project as a single .js file in dist. But this approach doesn't work well with nbb, since the .cljs is interpreted, the JS bundler does not see what libraries are being used. Instead I've now found another solution: just .zip your node_modules and put that zip file in dist/node_modules.zip and unzip it on the start of the action. This works surprisingly well, it only takes 0s. You can see it running https://github.com/borkdude/nbb-action-example/runs/7082296816?check_suite_focus=true. With all that said, I wonder if there are other alternative approaches to this. Perhaps npm supports stuff I don't know about. I've documented one other alternative: just call npm install on the action startup, which also works without problems but just takes a little bit of time. https://github.com/borkdude/nbb-action-example#dependencies

borkdude08:06:40

One other nice alternative might be to put the node_modules.zip in the releases section of the action and download it on startup

borkdude09:06:20

@delaguardo @cldwalker I've got a better approach now which doesn't even require you to bundle dependencies in your github repo: > Instead, the approach taken in this example is to zip the node_modules directory and upload it to Github Releases. This is done by taking the version from package.json, creating a pre-release for it and upload the zip file there. Once you're ready to release a new version for the public, you just flip the switch of the pre-release to release. The node modules are uploaded through the bb update-deps task and requires a valid GITHUB_TOKEN to be set with repository access. https://github.com/borkdude/nbb-action-example#dependencies

delaguardo10:06:53

That sounds good. Small note from my side - GH actions versioned based on any valid git tag which might be a branch, commit sha or even local copy in case of submodules. I don't know how many projects rely on that functionality and unfortunately i don't have a suggestion on how to improve this (maybe there is nothing to improve at all). Just want to share

borkdude10:06:50

Yes, the example can be used as such. It just relies on the version in package.json to find the node_modules.zip , not on the SHA

borkdude10:06:11

but the code itself (action.cljs) can be used from any sha

borkdude10:06:26

You just have to update the deps zip if you're changing deps

delaguardo10:06:18

even if it is located locally? then package.json must also has configured "repository"

borkdude10:06:22

no, not locally. you just should have a node_modules locally, but when the action is checked out, it will create it from the download. this is only done in the setup.mjs step

borkdude10:06:03

Potentially the node_modules.zip can also be uploaded to a separate project on github, dedicated to hosting these bundles

borkdude10:06:31

and then you can call the release my-action-node-modules-v1.2.0

delaguardo10:06:30

wow) please don't) JS dependency hell and package.json are already complex enough

borkdude10:06:36

this is not so complex. it just moves the garbage that you would otherwise check into git source control (yuck) to github releases

borkdude10:06:10

What I had before was just to check into the node_modules.zip into source control. It is a little bit easier, but also... checking 1mb zip files into source control :(

delaguardo10:06:21

I agree in general but personally I can tolerate having big archives in the repo if it can guaranties it will work in almost any cases. πŸ™‚ The complexity I see mostly in amount of places you have to reach to get everything you need for stable work. With node_modules in release there will be package.json, package-lock.json, released node_modules with almost identical content and purpose. Also, in case of archive in releases, it will rely on one more proprietary feature of github. I know how it sounds when we talk about GH Actions but right now the sources for action might be hosted anywhere πŸ™‚

delaguardo10:06:43

And please don't get me wrong I like your approach πŸ™‚ probably my thoughts are just a result of some kind of trauma caused by necessity to work with many JS tools in the past πŸ™‚

borkdude10:06:53

Sure, dist/node_modules.zip works too. If there is not too much churn in the dependencies, the file should not change so often, so that may be the preferred option

borkdude10:06:55

Just running npm install on action startup also works btw, but it takes much longer (5-6s instead of 0-1s)

borkdude11:06:07

Alright, I reverted to the previous idea of just putting your node_modules.zip in the repo: https://github.com/borkdude/nbb-action-example#dependencies

cldwalker13:06:49

Thanks for sharing your findings! Look forward to implementing this approach in my action

borkdude13:06:13

@cldwalker I'm a little bit torn between uploading the node_modules.zip to Github releases or checking it into source control. I just checked your node_modules and it's only 1mb zipped, so still ok I guess.

πŸ‘ 1
borkdude14:06:52

tar.gz seems even better

823983

borkdude14:06:08

tar.xz:

622712

borkdude14:06:08

Not sure if xz is readily available in Github runners, but tar.gz seems a safe bet

nice 1
borkdude11:06:49

The idea of using github releases (or some other blob store) for artifact bundles (versioned by some hash or version number) is something I've been doing at Nextjournal too. It seems that idea is getting more popular, e.g. this build system also does it: https://moonrepo.dev/

martinklepsch13:06:24

(def json-str (await (slurp "some.json")))
(js/JSON.parse json-str) ; -> returns JS obj

(js/JSON.parse (await (slurp "some.json"))) 
;; -> Unexpected token o in JSON at position 1
Not sure if this is expected but felt worth reporting πŸ™‚

borkdude13:06:08

This is expected, await only works top level.

πŸ‘ 1
borkdude13:06:29

await is only intended as a REPL tool

borkdude13:06:48

For the rest you should use promesa or direct promises

borkdude13:06:19

user=> (require '[promesa.core :as p])
nil
user=> (nbb.core/await (p/-> (nbb.core/slurp "package.json") (js/JSON.parse)))

borkdude13:06:51

or use fs/readFileSync :)

martinklepsch15:06:59

Cool, I did use the above in the REPL but thought it might be a limitation πŸ™‚

martinklepsch15:06:25

Is it possible that run-all-tests is missing from what’s provided of clojure.test?

borkdude15:06:50

await only works if the promise that is awaited can be inspected as a top level value by nbb That might be missing, feel free to post an issue.

πŸ‘ 1
borkdude17:06:03

Fixed on master. Will release new version soon

borkdude21:06:20

@U050TNB9F Available in nbb 0.5.120 now

πŸ™Œ 1