Allow to easily deploy to `gh_pages`
Closed this issue · 7 comments
If I have a javascript project with a Package
that builds the frontend bundle, it should be really easy to add an Executable
that will deploy that built frontend bundle to the gh-pages
branch on github.
It should not modify your local git checkout state in any relevant way.
Possible api:
export const website = garn.javascript
.mkNpmProject({
description: "The garn.io website",
nodeVersion: "18",
src: ".",
})
.addPackage("build", "npm run build ; mv build/* $out/")
.addGhPagesDeploy("build");
// or:
.add(ghPagesDeploy("build", "npm run build ; mv build/* $out/"))
// or: (@soenkehahn's personal favorite)
.add(ghPagesDeploy("build"))
Maybe even .add(ghPagesDeploy())
and the name defaults to something like deploy-gh-pages
, since most people probably don't care about customizing that, and it's not immediately obvious what the argument represents.
So the ghPagesDeploy
function needs to somehow know, which Package
to deploy to the gh-pages
branch. That's what the "build"
argument does.
Ah! It'd be nice if the argument were somehow of type Package
then. Though unclear how to do that nicely (cf. #396)
Yeah we spoke about something like this maybe:
.add(ghPagesDeploy(self => self.build))
But ideally ghPagesDeploy
could be made to work with all of these alternatives:
.add(ghPagesDeploy("build"))
.add(ghPagesDeploy(self => self.build))
.add(self => ghPagesDeploy(self.build)(self))
Yeah, exactly. So one option that @alexdavid and I were thinking of is that
Project.add
doesn't do much to make these things super convenient. Its type would just be something like<T extends Project, U extends Project>(p: T) => U
.- When you write a plugin, you can tweak this as much as you want. For example
ghPagesDeploy
could be overloaded and allow parameters of typestring
(thePackage
name on theProject
),Package
(if you happen to have aPackage
handy), but also(p: T) => Package
(so that you could write.add(ghPagesDeploy(self => self.build))
). Or it could be much simpler. - We could provide some helper functions that make it easy to write these plugins. For example if you just want to add a field to a project a helper could give you all the above options I think.
But yeah, this needs some api design work. :)
But ideally ghPagesDeploy could be made to work with all of these alternatives
Yeah, though whenever you have multiple ways of calling things, types and documentation get worse.
.add(self => ghPagesDeploy(self.build)(self))
Why the second self
application?
Maybe also:
.add({self} => ghPagesDeploy(self.build))
For backwards-compatibility.
This problem happens for addPackage
etc too - a unified solution would be nice.
Yeah, though whenever you have multiple ways of calling things, types and documentation get worse.
Yeah, although we'd probably only document a simple case like .add(ghPagesDeploy(self => self.build))
, but under the hood .add
is simple enough to grok for anyone to use the other syntaxes easily.
Why the second self application?
We were assuming the type of .add
is <T extends Project, U extends Project>(p: T) => U
, so a garn plugin implementation that adds a foo
helper would look something like this:
.add(self => ({
...self,
foo: () => console.log("foo"),
}))
If we want to support add(self => ghPagesDeploy(self.build))
then the type of add will artificially add another self
parameter. E.g. here is a noop plugin:
.add(self => self => ({ ...self }))
This is analogous to nodejs http server middleware where most of the time it just works out of the box like
app.use(someMiddleware())
But occasionally you see simple wrappers like this:
app.use((req, res, next) => {
if (req.url === '/') someMiddleware()(req, res, next)
else otherMiddleware()(req, res, next)
})