Tutorial: Publishing your own Github blog (Part 1) Part 1: how to easily to set up and manage your own blog Sep 10, 2022 Hugo Ferreira Introduction This is the first part in a series of articles about creating and publishing technical content on publicly available hosts. The goal is to set-up a source to write and publish a static website to various target hosts. I want to make this as easy and painless as possible, so I have opted to use Markdown to write the contents, use code editing tools and version control to manage the content and use a static site generator to be able to cross-publish the full site or single posts to various destinations (hosts). The aim is to keep these hosts synchronized and facilitate updating when required. I will have one repository for the site's sources that will be kept private. I assume that all content that is published is public. I will use Java as the base technology to develop, maintain and publish the sites. In particular the tools used were selected to facilitate the documentation of Java and Scala 3 projects, including library APIs. This includes the use of the Mill build tool (Mill documentation) to develop and execute the required scripts to generate and publish the content. Getting started We start off by creating a Github repository with the sources for the websites. This is my private source where I keep my research and unfinished work. It also contains the final rendered pieces that can then me moved to the destination hosts. Then we create the Github repository where the website is published. Go to your github account and press the create a new repository option; Create the repository name (in my case tech4rd) for your site using GitHub pages; Add a description (Articles on software development, programming stuff, embedded systems, sensors and electronics.); Make sure the site is public (don't keep their anything private); Select the option to initialize the repository with a README.md file; Select the option to add an initial .gitignore file (use the Scala template); Click the create a template button. Github documentation states that: "GitHub Pages sites are publicly available on the internet, even if the repository for the site is private." Because these sites are public, don't store any personal, private or sensitive data there. Now we can create the website source repository. Go to the repository you created to keep the sources of the site; Create a index.md or index.html file as the site's initial content: Don't place this file in the project's root of the source repository; Select add -> create a new file; Input both the path and the file: docs/index.md Place some content in this page; We then configure the publishing source: In the source site click on the Settings tab; Go to the Code and Automation section; Under this section click on Pages to open the Github pages configuration page: Select Source for a specific branch or leave as None. Select the main branch and select /docs as the site content folder. Don't forget to press the save button. When you do this the site's URL is provided for you; Note that the site will not be immediately available. It can take up to 10 minutes for each change to be reflected in the site; You can then choose a theme for the Jekyll static site generator if you use the gh-pages branch. We are going to use another static site generator, so leave it as is; Add the website link to you Github repository page Go to the project's Github repository site; Click on the configuration wheel of the About field; Click on the Website field and paste the previously configured URL into it; Fill in the Description and Topics as desired. For example: Description: Articles on software development and embedded systems. Topics: java scala programming electronics embedded-systems software-development sensors. You can now view the initial content of your site. From the sites repository, click on the URL you have just saved. You should be able to see your contents. Automatically generated sites In the example above, we provided a Markdown file and the content was automatically made available as HTML. Several companies provide hosting platforms that can automatically render Markdown files as HTML. The site's content can be, for example, standard text files that can be viewed with the web interface of a code repository. It can also contain HTML content for a project or personal website. Examples of this include Github pages (used above) and Gitlab pages. Generating a static website based only on Markdown, may not be enough for all but the simplest website. In these cases, one can use several Markdown files and use links among them. This allows one to set up simple static sites that include: manually generated static menus or indexes, use of links between content and adding any formatting that is supported by Markdown syntax. It is important to note that these hosts support the parsing of Markdown files that are not "standard". We have for example Github's and Gitlab's flavoured versions of Markdown. These versions of Markdown include for example encoding "for mentions", "emojis" and "issues" that can be placed in the source. These features facilitate interaction with the code repository and are parsed using the host's default parsers. In some cases, the online Web interface also allows for additional configurations and facilitates the editing of the content. There is no standard for Markdown. The closest we have to a standard is John Gruber’s canonical description of Markdown’s syntax. A good source for a complete description of Markdown (including cheat sheets), is the Markdown Guide. Here you can also find a list of extended-syntax versions of the Markdown language that includes for example the Commonmark and R Markdown variants. It is also possible to add themes, for example in GitHub pages, when using Markdown-only sites. Internally, Github pages uses Jekyll. In this case, the HTML files will automatically be created via this static site generator. No need to install or invoke the static site tools. However, to activate and use the theme, it is necessary for you to set up the YAML front matter that specifies the layout of each HTML output. Alternatively, one can use a static site generator by incorporating it into the CI/CD workflow1 or use it locally to manually create and publish the site's contents to the hosts' website location. We will look at the details in the section on static site generation. Static site generation Static site generators process a set of source files (written, for example, in MarkDown, AsciiDoc (see AsciiDoc in Wikipedia) and ReStructuredText) and generate the HTML content. Usually each source file is converted into a corresponding HTML file. Files in HTML can also be used as sources, but they are usually not processed by the static site generator. In addition to this, these tools also make use of templates (such as Freemarker or ThymeLeaf) to define the layout and look of the website. The templates let us configure the sites' menus, add headers and footers to the HTML pages, provide social media links, social share menus and 404 error handling for several hosts. They also allow one to place JavaScript in the HTML pages so that additional functionality can be made available. Examples include adding Google Analytics scripts, estimating read times for the posts, show maths expressions (MathJax, MathJS, KaTex), draw flowcharts (Mermaid-Js, Flowchart.js), render plots (ChartJS, Plotly, Chartist-Js, RawGraphs.io, d3js, c3js, nvd3) and use icons (FeatherIcons, IonIcons, FontAwesome, Tabler, css.gg). There are quite a few static site generators out there. These include for example: Docusaurus.io (Docusaurus in Github), Jekyll (Jekyll in Github), sphinx-doc, Pamflet (Pamflet in Github), Nanoc, GitBook, Paradox (Paradox in Github), GoHugo and AsciiDoctor. Many of these tools are developed in Ruby, Go or Python. I have opted to use JVM based static site generators to make it easy to automate the process - I only depend on the JVM. Maven packages that can be installed via the Ivy package manager and Maven or Gradle plugins to run the necessary tools. No need to deal with operating system package installation once the Java system is installed. This also makes the use of CI/CD workflows easier to update a Blog or launch a new software release. Some of these static site generators include: JBake (JBake in github), Laika (Laika Github), Pamflet and Paradox. Laika is a interesting case in that it is also capable of generating documents of other formats such as PDF. I also include in this category tools that can be used to generate Java or Scala API documentation. In the case of Java we have Javadoc. For Scala we will focus on ScalaDoc specifically for Scala3 (see the Scala3 ScalaDoc Guide and Scala3 ScalaDoc Usage webpages). Note that ScalaDoc is part of the Scala3 compiler, also known as Dotty. The Scala3 ScalaDoc tool is a static site generator in and of itself. In addition to the HTML templates, the source files can also be preprocessed prior to conversion. In particular, I am interested in documenting software. The MDoc (MDoc in Github) can be used to compile code snippets embedded in the Markdown sources. Depending on the static site generator we also have build tool plugins for the Scala ecosystem. For example, the Sbt-site(Sbt-site Github) plugin can use several generators to create a static website. The Mill build tool includes plugins for Docusaurus, JBake and MDoc plugin. I will first show you how to set-up and use a JBake static site. More concretely I will configure, populate and publish a blog. Later I will also describe how to use ScalaDoc and MDoc to document software and keep this documentation up to date with the software repository. Workflow Before getting into the nitty gritty, let's first take a look at what the workflow of publishing a site might look like. To generate a site we basically take a set of sources, for example Markdown files and drawings, and transform them into the website's artifacts. These artifacts are usually HTML files, but may include PDF files and images (for example in the PNG or SVG formats). Usually a single source file is transformed into a single HTML file, but in general this is not a strict requirement. A source file may go through several transformations before the final output is generated. For example a Markdown file may have its code fences compiled by the MDoc plugin resulting in a changed source. This file is then processed by JBake using Freemarker templates to produce the final HTML file. The various transformations may be applied by several tools, each of which may need their own configuration. For example, we may want to generate HTML pages with a specific layout that may include pre-compiled content, specific menus, headers and footers. Freemarker for example allows the use of templates and a domain specific language (DSL) that defines the look and feel of the final HTML page. In this case, the static site generator takes as input a Freemarker template and a Markdown source file to generate the final output. Sometimes the source file itself may include configurations used to tweak the output. For example, the MDoc plugin allows us to tag each code fence to define the type of output we want or, a Markdown file may have a header. It is important to point out that anyone is free to include manually edited HTML pages to the site's contents. In addition to this, Markdown for example, allows one to embed HTML snippets that will be kept unaltered. Compiling a site means taking a set of sources that are located in a given path, transforming these and placing them in the site's final directory. Some files may not be processed at all. For example images may be copied, as is, to the site's destination folder. Generally the location of the source files within the source directory determines how and where the content is made available. For example, blogs may have a directory specifically set aside to contain posts indexed by the publishing date. Usually the transformed files are placed in a local private directory where they can be served and checked locally. Once the content has been checked (or not), it can be published to the final public serving host. The compilation of the website is usually done by executing one or more commands of a static site generator tool at the command line. This tool must be configured prior to execution. Such configurations may include the path to the site's sources and transformation workflow to be used. Usually the sources need to be made available in a specified path and with a required directory structure. As I have pointed out, we may also need to configure the use of other tools and their respective configurations. The site generator command is usually invoked at the root of the site's sources. However, it may advantageous to invoke the static site generator via a build tool such as Mill. It allows us to customize our workflow so that we can use several tools including specific preprocessing transformers for our website. We are free to implement our own transformations tasks and embed them into the workflow of our Mill scripts that do source compilation and unit testing. We can also use Mill with CI/CD pipelines to automatically publish new content. Another advantage of using a build tool like Mill is that we only provide a Mill command line script with our sources and a Mill build script. Mill will then download and install itself and any of the required dependencies (such as the JBake tools) before executing the build script. When using CI/CD, we don't have to worry about downloading and installing Mill or any additional tools. In the next section we will use a Mill JBake plugin to generate a static site. JBake So the first question is, why JBake? JBake is a mature Java tool that has good documentation and large user community. So it should provide most of us with what we need or want (analytics, icons, menus, etc.). In particular, JBake has been extensively used to document open software projects and implement blogs and personal sites. Having said this, it does not seem to be as popular as Jekyll or GoHugo but, it is well supported and several templates are available. In particular it can use the Freemarker, Groovy Simple and Markup, Thymeleaf, Jade and Pebble template engines. To set up a JBake static site consists of the following steps: Download and install the JBake tool; Create a directory for the website's source; Populate the directory with JBake's default configuration that uses Freemarker templates; Customize the templates if this is necessary; Add to or change content in the site's sources directory (assets, content, templates); Use JBake to generate the website's final output (HTML, XHTML); Preview the contents (includes a "watch" mode to automatically preview and update the content); Publish the contents. To update the website we need only add or change the website's content and repeat the steps that generate the final output and publish the contents. JBake is used via the command line to perform all theses actions. It is also possible to use command line parameters, change configuration files and set environment variables to configure JBake's output. For full details see JBake's documentation. I strongly suggest you keep the site's sources under version control. Either place these sources in an existing repository that you want to document, or place this in a separate repository where you keep only the website's source code. In this example, we will work on a blog, so we use a separate repository that contains only the site's sources. Installing Mill In this article we will use Mill's JBake plugin. This allows us to download and execute JBake without installing this tool in the host operating system. This is advantageous when using a CI/CD pipeline in a virtual machine. All the static website generation setup and configuration is done as documented in JBake's site. The execution of JBake however, is done via a Mill build script and the corresponding Mill tasks encoded in that script. So let's start off by installing and writing up our Mill script: First place yourself at the site's source repository: $ cd ~/VSCodeProjects/blog Next, download the latest release of Mill. Make sure you download the "starter" script (not the assembly). It is named with the Mill version and is less the 2 KBytes large. Here is an example of downloading the script: $ wget https://github.com/com-lihaoyi/mill/releases/download/0.10.4/0.10.4 Next we rename the script to mill and make sure the script has the permission to execute: $ mv 0.10.4 mill $ chmod +x ./mill For those of you in Windows, it may be advantageous for you to download and use millw. It is a drop-in replacement for mill that has a millw.bat version for windows. I also found in the past, that it was able to download and use snapshot versions of Mill, which the original script failed to do. wget https://raw.githubusercontent.com/lefou/millw/main/millw wget https://raw.githubusercontent.com/lefou/millw/main/millw.bat chmod +x ./millw A this point you should have the scripts ready to run: $ ls -l Output: total 376 -rwxrwxr-x 1 user user 1714 mai 6 11:24 mill -rwxrwxr-x 1 user user 187411 mai 7 17:25 millw -rw-rw-r-- 1 user user 167228 mai 7 17:26 millw.bat -rw-rw-r-- 1 user user 45 abr 7 18:43 README.md In this article I am going to use a specific version of Mill. To ensure that you use the correct version, create the .mill-version file and place the Mill version inside this file: $ touch .mill-version $ echo 0.10.4 >> .mill-version We can now check the Mill version using the following command: $ ./mill -i --version Output: Mill Build Tool version 0.10.4 Java version: 11.0.15, vendor: Private Build, runtime: /usr/lib/jvm/java-11-openjdk-amd64 Default locale: en_US, platform encoding: UTF-8 OS name: "Linux", version: 5.13.0-40-generic, arch: amd64 Note that when you run this command for the first time, the correct version of Mill will first be downloaded and then used. All subsequent calls to mill or millw will use the installed version. To see what version has already been downloaded, execute: ls /home/use/.cache/mill/download/* Set up the Mill JBake module Mill scripts provides a set of modules, which are Scala 2 objects, that have several methods (referred to as tasks or targets) that allows one to: compile mixed Java and Scala projects, execute the code's main methods, and run unit tests. These modules can be "mixed" into a single compilation unit when we need to combine several functionalities into a single module. Many useful modules are provided out-of-the-box, but it is not possible to foresee or provide all required modules. Mill therefore allows anyone to distribute their modules as $3^{rd}$ party plugins. These plugins are provided as Maven artifacts that are downloaded via a Coursier backend using Ammonite's magic imports. Mill-JBake is one such plugin that can be automatically downloaded, installed and used via Mill. We won't go into details here, but in the next steps I'll describe how to: Create a Mill script file; Write-up a simple Mill module that uses Mill-JBake to give us access to the JBake tool; Configure the JBake version to use; Execute JBake to initialize the repository. First create the build script at the projects' root. In our case it is the blog code repository. Do as follows: $ cd ~/VSCodeProjects/blog $ touch build.sc Then add the following code to the build.sc file: import mill._ import $ivy.`de.tototec::de.tobiasroeser.mill.jbake::0.3.0` import de.tobiasroeser.mill.jbake._ object site extends JBakeModule { def jbakeVersion = "2.6.7" // Default in 0.3.0 override def jbakeProcessMode: JBakeModule.ProcessMode = JBakeModule.SubProcess } Let's take a look at what the code above does. The line shown below uses Ammonite's magic import to download and install the Mill-JBake plugin: import $ivy.`de.tototec::de.tobiasroeser.mill.jbake::0.3.0` These lines import the Mill default modules and the Mill-JBake module: import mill._ import de.tobiasroeser.mill.jbake._ Next we set the version of the JBake tool that will be downloaded and used: def jbakeVersion = "2.6.7" The following line ensures that JBake is launched in a separate JVM. I have found that for later versions of JBake, using Mill's JVM to execute the commands, results in errors. // Default in 0.3.0 override def jbakeProcessMode: JBakeModule.ProcessMode = JBakeModule.SubProcess The name of the module is set to site. Mill's convention is that a project may have several modules. The source of each module is placed in a directory with the same name located at the project's root. The project's root is where the build.sc file is found. So in our case we first create the module's source directory: ~/VSCodeProjects/blog$ mkdir site The site module extends de.tobiasroeser.mill.jbake.JBakeModule. that provides us access to the JBake tool via several optional configuration values (such as jbakeVersion shown above) and the JBake commands (such as initializing, compiling ("baking") and serving content). All the commands we execute for a module is prefixed with the module's name. So in this case, all commands will explicitly start with site. To see what targets are available either of these commands can be used: ~/VSCodeProjects/blog./millw -i resolve site._ ~/VSCodeProjects/blog./mill -i resolve site._ Output (note that the first time you run this, the output will include a list of the downloaded Mill-JBake Jars): [1/1] resolve site.jbake site.jbakeClasspath site.jbakeDistributionDir site.jbakeDistributionZip site.jbakeInit site.jbakeRun site.jbakeServe site.jbakeVersion site.jbakeWorker site.sources At this point we are ready to create the site's content. Let's start off by initializing the site with the default Freemarker template: ~/VSCodeProjects/blog$ ./millw -i site.jbakeInit Output: Compiling /home/user/VSCodeProjects/blog/build.sc [7/7] site.jbakeInit JBake v2.6.7 (2021-05-14 21:54:29[GMT+01:00]) [http://jbake.org] Base folder structure successfully created. This command sets up an example site using the default FreeMarker template. It adds the required directories and example content. This includes assets such as images, icons, CSS formatting, JavaScript libraries, FreeMarker templates and some AsciiDoc content. We can now take a look at the site's source directory as follows: ~/VSCodeProjects/blog$ tree site/ Output: site/ └── src ├── assets │ ├── css │ │ ├── asciidoctor.css │ │ ├── base.css │ │ ├── bootstrap.min.css │ │ └── prettify.css │ ├── favicon.ico │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ └── glyphicons-halflings-regular.woff │ ├── img │ │ └── beach.jpg │ └── js │ ├── bootstrap.min.js │ ├── html5shiv.min.js │ ├── jquery-1.11.1.min.js │ └── prettify.js ├── content │ ├── about │ │ └── jbake_logo.png │ ├── about.html │ └── blog │ └── 2013 │ ├── fifth-post.adoc │ ├── first-post.html │ ├── fourth-post.adoc │ ├── second-post.md │ └── third-post.adoc ├── jbake.properties └── templates ├── archive.ftl ├── feed.ftl ├── footer.ftl ├── header.ftl ├── index.ftl ├── menu.ftl ├── page.ftl ├── post.ftl ├── sitemap.ftl └── tags.ftl 11 directories, 32 files If you are working in a Git repository, don't forget to add the .gitignore file in the project's root with the following lines: /.metals /.vscode /out The next step is to compile or "bake" the site. ~/VSCodeProjects/blog$ ./mill -i site.jbake Output of compilation [7/7] site.jbake JBake v2.6.7 (2021-05-14 21:54:29[GMT+01:00]) [http://jbake.org] 10:16:50.269 INFO org.jbake.app.Oven - Baking has started... Warning: Nashorn engine is planned to be removed from a future JDK release 10:16:50.507 INFO c.o.common.jna.ONative - Detected limit of amount of simultaneously open files is 1048576, limit of open files for disk cache will be set to 523776 10:16:50.548 INFO c.o.common.jna.ONative - 33429823488 B/31881 MB/31 GB of physical memory were detected on machine 10:16:50.549 INFO c.o.common.jna.ONative - Soft memory limit for this process is set to -1 B/-1 MB/-1 GB 10:16:50.549 INFO c.o.common.jna.ONative - Hard memory limit for this process is set to -1 B/-1 MB/-1 GB 10:16:50.549 INFO c.o.common.jna.ONative - Path to 'memory' cgroup is '/user.slice/user-1000.slice/user@1000.service' 10:16:50.549 INFO c.o.common.jna.ONative - Mounting path for memory cgroup controller is '/sys/fs/cgroup/memory' 10:16:50.550 INFO c.o.common.jna.ONative - cgroup soft memory limit is 9223372036854771712 B/8796093022207 MB/8589934591 GB 10:16:50.550 INFO c.o.common.jna.ONative - cgroup hard memory limit is 9223372036854771712 B/8796093022207 MB/8589934591 GB 10:16:50.550 INFO c.o.common.jna.ONative - Detected memory limit for current process is 33429823488 B/31881 MB/31 GB 10:16:50.551 INFO c.o.o.c.e.OMemoryAndLocalPaginatedEnginesInitializer - JVM can use maximum 7972MB of heap memory 10:16:50.551 INFO c.o.o.c.e.OMemoryAndLocalPaginatedEnginesInitializer - Because OrientDB is running outside a container 12% of memory will be left unallocated according to the setting 'memory.leftToOS' not taking into account heap memory 10:16:50.551 INFO com.orientechnologies - OrientDB auto-config DISKCACHE=20 083MB (heap=7 972MB os=31 881MB) 10:16:50.553 INFO c.o.o.c.e.l.OEngineLocalPaginated - System is started under an effective user : `user` 10:16:50.553 INFO c.o.o.c.e.l.OEngineLocalPaginated - Allocation of 305261 pages. 10:16:51.226 INFO c.o.o.c.s.m.ODirectMemoryStorage - Storage 'memory:cache' is created under OrientDB distribution : 3.0.37 - Veloce (build 6a0e4724c10d51a0b19700fca46da8e41ae006f5, branch UNKNOWN) 10:16:52.199 INFO org.jbake.template.ModelExtractors - register new extractors for document type: masterindex 10:16:52.200 INFO org.jbake.template.ModelExtractors - register new extractors for document type: tagsindex 10:16:52.200 INFO org.jbake.template.ModelExtractors - register new extractors for document type: sitemap 10:16:52.355 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/about.html]... : new 10:16:52.364 INFO org.jbake.parser.AsciidoctorEngine - Initializing Asciidoctor engine... 10:16:54.177 INFO org.jbake.parser.AsciidoctorEngine - Asciidoctor engine initialized. 10:16:54.325 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/fifth-post.adoc]... : new 10:16:54.329 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/first-post.html]... : new 10:16:54.392 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/fourth-post.adoc]... : new 10:16:54.496 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/second-post.md]... : new 10:16:54.525 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/third-post.adoc]... : new 10:16:54.525 INFO org.jbake.app.Crawler - Content detected: 10:16:54.525 INFO org.jbake.app.Crawler - Parsed 1 files of type: page 10:16:54.526 INFO org.jbake.app.Crawler - Parsed 5 files of type: post 10:16:54.680 INFO org.jbake.app.Renderer - Rendering archive [/home/user/VSCodeProjects/blog/out/site/jbake.dest/archive.html]... done! 10:16:54.687 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/about.html]... done! 10:16:54.698 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/fifth-post.html]... done! 10:16:54.701 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/fourth-post.html]... done! 10:16:54.704 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/third-post.html]... done! 10:16:54.706 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/second-post.html]... done! 10:16:54.709 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/first-post.html]... done! 10:16:54.733 INFO org.jbake.app.Renderer - Rendering feed [/home/user/VSCodeProjects/blog/out/site/jbake.dest/feed.xml]... done! 10:16:54.740 INFO org.jbake.app.Renderer - Rendering masterindex [/home/user/VSCodeProjects/blog/out/site/jbake.dest/index.html]... done! 10:16:54.751 INFO org.jbake.app.Renderer - Rendering sitemap [/home/user/VSCodeProjects/blog/out/site/jbake.dest/sitemap.xml]... done! 10:16:54.756 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/asciidoctor.css]... done! 10:16:54.756 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/base.css]... done! 10:16:54.756 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/bootstrap.min.css]... done! 10:16:54.757 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/prettify.css]... done! 10:16:54.757 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/favicon.ico]... done! 10:16:54.757 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/fonts/glyphicons-halflings-regular.eot]... done! 10:16:54.758 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/fonts/glyphicons-halflings-regular.svg]... done! 10:16:54.758 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/fonts/glyphicons-halflings-regular.ttf]... done! 10:16:54.758 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/fonts/glyphicons-halflings-regular.woff]... done! 10:16:54.758 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/img/beach.jpg]... done! 10:16:54.759 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/js/bootstrap.min.js]... done! 10:16:54.759 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/js/html5shiv.min.js]... done! 10:16:54.759 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/js/jquery-1.11.1.min.js]... done! 10:16:54.759 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/js/prettify.js]... done! 10:16:54.760 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/content/about/jbake_logo.png]... done! 10:16:54.760 INFO org.jbake.app.Oven - Baking finished! 10:16:54.760 INFO org.jbake.app.Oven - Baked 10 items in 4491ms 10:16:54.761 INFO c.o.orient.core.db.OrientDBEmbedded - - shutdown storage: cache... And then serve the site at a local address: ~/VSCodeProjects/blog$ ./mill -i site.jbakeServe Output of serving a JBake site [8/8] site.jbakeServe JBake v2.6.7 (2021-05-14 21:54:29[GMT+01:00]) [http://jbake.org] 10:19:35.605 INFO org.jbake.app.Oven - Baking has started... Warning: Nashorn engine is planned to be removed from a future JDK release 10:19:35.824 INFO c.o.common.jna.ONative - Detected limit of amount of simultaneously open files is 1048576, limit of open files for disk cache will be set to 523776 10:19:35.870 INFO c.o.common.jna.ONative - 33429823488 B/31881 MB/31 GB of physical memory were detected on machine 10:19:35.870 INFO c.o.common.jna.ONative - Soft memory limit for this process is set to -1 B/-1 MB/-1 GB 10:19:35.870 INFO c.o.common.jna.ONative - Hard memory limit for this process is set to -1 B/-1 MB/-1 GB 10:19:35.870 INFO c.o.common.jna.ONative - Path to 'memory' cgroup is '/user.slice/user-1000.slice/user@1000.service' 10:19:35.871 INFO c.o.common.jna.ONative - Mounting path for memory cgroup controller is '/sys/fs/cgroup/memory' 10:19:35.871 INFO c.o.common.jna.ONative - cgroup soft memory limit is 9223372036854771712 B/8796093022207 MB/8589934591 GB 10:19:35.871 INFO c.o.common.jna.ONative - cgroup hard memory limit is 9223372036854771712 B/8796093022207 MB/8589934591 GB 10:19:35.871 INFO c.o.common.jna.ONative - Detected memory limit for current process is 33429823488 B/31881 MB/31 GB 10:19:35.872 INFO c.o.o.c.e.OMemoryAndLocalPaginatedEnginesInitializer - JVM can use maximum 7972MB of heap memory 10:19:35.872 INFO c.o.o.c.e.OMemoryAndLocalPaginatedEnginesInitializer - Because OrientDB is running outside a container 12% of memory will be left unallocated according to the setting 'memory.leftToOS' not taking into account heap memory 10:19:35.872 INFO com.orientechnologies - OrientDB auto-config DISKCACHE=20 083MB (heap=7 972MB os=31 881MB) 10:19:35.874 INFO c.o.o.c.e.l.OEngineLocalPaginated - System is started under an effective user : `user` 10:19:35.874 INFO c.o.o.c.e.l.OEngineLocalPaginated - Allocation of 305261 pages. 10:19:36.562 INFO c.o.o.c.s.m.ODirectMemoryStorage - Storage 'memory:cache' is created under OrientDB distribution : 3.0.37 - Veloce (build 6a0e4724c10d51a0b19700fca46da8e41ae006f5, branch UNKNOWN) 10:19:37.468 INFO org.jbake.template.ModelExtractors - register new extractors for document type: masterindex 10:19:37.470 INFO org.jbake.template.ModelExtractors - register new extractors for document type: tagsindex 10:19:37.470 INFO org.jbake.template.ModelExtractors - register new extractors for document type: sitemap 10:19:37.635 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/about.html]... : new 10:19:37.644 INFO org.jbake.parser.AsciidoctorEngine - Initializing Asciidoctor engine... 10:19:39.505 INFO org.jbake.parser.AsciidoctorEngine - Asciidoctor engine initialized. 10:19:39.645 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/fifth-post.adoc]... : new 10:19:39.649 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/first-post.html]... : new 10:19:39.728 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/fourth-post.adoc]... : new 10:19:39.834 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/second-post.md]... : new 10:19:39.870 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/third-post.adoc]... : new 10:19:39.871 INFO org.jbake.app.Crawler - Content detected: 10:19:39.871 INFO org.jbake.app.Crawler - Parsed 1 files of type: page 10:19:39.871 INFO org.jbake.app.Crawler - Parsed 5 files of type: post 10:19:39.973 INFO org.jbake.app.Renderer - Rendering archive [/home/user/VSCodeProjects/blog/out/site/jbake.dest/archive.html]... done! 10:19:39.978 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/about.html]... done! 10:19:39.990 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/fifth-post.html]... done! 10:19:39.993 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/fourth-post.html]... done! 10:19:39.996 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/third-post.html]... done! 10:19:39.999 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/second-post.html]... done! 10:19:40.002 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/first-post.html]... done! 10:19:40.024 INFO org.jbake.app.Renderer - Rendering feed [/home/user/VSCodeProjects/blog/out/site/jbake.dest/feed.xml]... done! 10:19:40.031 INFO org.jbake.app.Renderer - Rendering masterindex [/home/user/VSCodeProjects/blog/out/site/jbake.dest/index.html]... done! 10:19:40.043 INFO org.jbake.app.Renderer - Rendering sitemap [/home/user/VSCodeProjects/blog/out/site/jbake.dest/sitemap.xml]... done! 10:19:40.047 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/asciidoctor.css]... done! 10:19:40.047 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/base.css]... done! 10:19:40.047 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/bootstrap.min.css]... done! 10:19:40.048 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/prettify.css]... done! 10:19:40.048 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/favicon.ico]... done! 10:19:40.048 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/fonts/glyphicons-halflings-regular.eot]... done! 10:19:40.048 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/fonts/glyphicons-halflings-regular.svg]... done! 10:19:40.049 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/fonts/glyphicons-halflings-regular.ttf]... done! 10:19:40.049 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/fonts/glyphicons-halflings-regular.woff]... done! 10:19:40.049 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/img/beach.jpg]... done! 10:19:40.050 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/js/bootstrap.min.js]... done! 10:19:40.050 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/js/html5shiv.min.js]... done! 10:19:40.050 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/js/jquery-1.11.1.min.js]... done! 10:19:40.050 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/js/prettify.js]... done! 10:19:40.051 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/content/about/jbake_logo.png]... done! 10:19:40.051 INFO org.jbake.app.Oven - Baking finished! 10:19:40.051 INFO org.jbake.app.Oven - Baked 10 items in 4446ms 10:19:40.052 INFO c.o.orient.core.db.OrientDBEmbedded - - shutdown storage: cache... 10:19:40.091 INFO org.jbake.launcher.BakeWatcher - Watching for (content, template, asset) changes in [/home/user/VSCodeProjects/blog/site/src] 10:19:40.141 INFO org.jbake.launcher.JettyServer - Serving out contents of: [/home/user/VSCodeProjects/blog/out/site/jbake.dest] on http://localhost:8820/ 10:19:40.141 INFO org.jbake.launcher.JettyServer - (To stop server hit CTRL-C) You can then preview it in your browser at this URL. Here is an image of the initial example site (shown using Dark Reader): Note that JBake will monitor changes in the site's source and automatically update the site's content. To stop the automatic update and serving of the website simple press the keys Ctrl-C. The server will terminate as shown below: ^C 18:50:11.633 WARN c.o.orient.core.OSignalHandler - Received signal: SIGINT 18:50:11.635 INFO c.o.orient.core.Orient - Orient Engine is shutting down... 18:50:11.749 INFO c.o.orient.core.Orient - Clearing byte buffer pool 18:50:11.803 INFO c.o.orient.core.Orient - OrientDB Engine shutdown complete Because we generated a static site, it is also possible for us to simply point our browser to the index.html file. From the output above we can see that the site's index file is located in the following directory: /home/user/VSCodeProjects/blog/out/site/jbake.dest If we open the index.html file, we will get a similar page as above. However, many of the assets will not appear correctly. For example, an image using an absolute link will not be rendered in the browser. This is because all links that absolute, will only resolve to the site's root, if served by an HTTP web server. So, for example, the images in the img directory and cascading style sheets in the css directory will not be found and used correctly, unless served by a web server. This is the reason why one should render the site using a web server. You can now look a the the JBake documentation do learn how to configure this tool. It is possible to: Configure the folders where the content, templates and assets are placed; Flag files and folders to be ignored by JBake; Define the default status value used in the metadata headers (draft, published, published-date) Publishing If we use the default publishing source, as we did in the getting started section, your content is automatically published. You can configure the sources of Github pages to be kept in a specific branch, and place the sources in that branch's root or /doc folder. If you publish to the /docs folder you can also specify the custom domain name of your site in the /docs/CNAME file. Every time you merge changes to the source branch, Github publishes those pages. I have opted to place the source in one repository, and publish the content in another repository. I do this so that I can keep my sources private, which include drafts and notes. We have followed the instructions used for setting up Github pages using Jekyll. At this point, we have already created our source repository, generated a static site and tested it locally using the Mill JBake plugin. We also have our public site repository that will hold our static website that anyone can access via Github pages. However, because we are using Github free, we cannot publish our content automatically. One way to do this is to simply: Create and clone your public website repository; Configure your public website repository to contain a Github pages URL; Create and clone your private source repository; Use the Mill JBake plugin to develop and test the local copy of your static website in your private repository; When you are ready to publish: Delete your public website repository's source folder from your local copy(such as /home/user/VSCodeProjects/tech4rd/docs/); Copy the compiled static website from your copy of the private site (for example /home/user/VSCodeProjects/blog/out/site/jbake.dest/) to your copy of the public site (for example /home/user/VSCodeProjects/tech4rd/docs/); Push and commit the changes of your copy of the public website repository; Github pages will detect the update and publish your site Lets take a look at the build.sc Mill script code snippets defined in the site object extends JBakeModule. The set of methods, values and targets allow us to deploy the site as described above. The following line creates a path that point to the public website repository: def siteDestination: T[os.Path] = T { os.Path("/home/user/VSCodeProjects/tech4rd") } The Mill script assumes that the siteDestination path contains a valid git repository. This is the default path where the compiled website is copied to. The next code snipped shows the jbakeCopy target that does the actual copying: def jbakeCopy(args: String*) = T.command { val outPath = jbake().path val destination = if (args.size > 0) os.Path(args(0)) else siteDestination() val dest = destination / "docs" val exists = os.exists(dest) && os.isDir(dest) if (exists) { os.remove.all(dest) T.ctx().log.info(s"Copying site from '$outPath' to '$dest'") os.copy(outPath, dest) Some(destination) } else { T.ctx().log.info(s"Warning: destination does not exist - $dest. Site not deployed.") None } } The method above works as follows: It uses the jbake command to extract the destination folder where the compiled site exists. Note that if the website's sources have changed, jbake will automatically compile these sources; It then gets the destination path where the website's content will be copied to. If no path is passed into this target as a command line argument, then the siteDestination path will be used by default; The jbakeCopy target assumes the destination directory has a docs subfolder where the website's content must be copied to. This will allow us later to copy and publish additional elements, such as code examples or complete projects, that may be referred to in the website. If this subfolder does not exist, the process ends here; If the destination directory docs subfolder exists, then its contents are first deleted, and the new website's compiled content is copied into it; The method then returns the destination path if a copy was performed (Some(destination)) or None to indicate the copy failed. Next we show how to execute this target on a new site. First place yourself at the private source repository's directory: $ cd /home/user/VSCodeProjects/blog Output: ~/VSCodeProjects/blog$ pwd /home/user/VSCodeProjects/blog Next we invoke the jbakeCopy target as follows: ~/VSCodeProjects/blog$ ./mill -i site.jbakeCopy Output of `jbakeCopy` when website is compiled... Compiling /home/user/VSCodeProjects/blog/build.sc [7/9] site.jbake JBake v2.6.7 (2021-05-14 21:54:29[GMT+01:00]) [http://jbake.org] 18:32:25.715 INFO org.jbake.app.Oven - Baking has started... Warning: Nashorn engine is planned to be removed from a future JDK release 18:32:25.966 INFO c.o.common.jna.ONative - Detected limit of amount of simultaneously open files is 1048576, limit of open files for disk cache will be set to 523776 18:32:26.015 INFO c.o.common.jna.ONative - 33429823488 B/31881 MB/31 GB of physical memory were detected on machine 18:32:26.016 INFO c.o.common.jna.ONative - Soft memory limit for this process is set to -1 B/-1 MB/-1 GB 18:32:26.016 INFO c.o.common.jna.ONative - Hard memory limit for this process is set to -1 B/-1 MB/-1 GB 18:32:26.016 INFO c.o.common.jna.ONative - Path to 'memory' cgroup is '/user.slice/user-1000.slice/user@1000.service' 18:32:26.017 INFO c.o.common.jna.ONative - Mounting path for memory cgroup controller is '/sys/fs/cgroup/memory' 18:32:26.017 INFO c.o.common.jna.ONative - cgroup soft memory limit is 9223372036854771712 B/8796093022207 MB/8589934591 GB 18:32:26.017 INFO c.o.common.jna.ONative - cgroup hard memory limit is 9223372036854771712 B/8796093022207 MB/8589934591 GB 18:32:26.017 INFO c.o.common.jna.ONative - Detected memory limit for current process is 33429823488 B/31881 MB/31 GB 18:32:26.018 INFO c.o.o.c.e.OMemoryAndLocalPaginatedEnginesInitializer - JVM can use maximum 7972MB of heap memory 18:32:26.018 INFO c.o.o.c.e.OMemoryAndLocalPaginatedEnginesInitializer - Because OrientDB is running outside a container 12% of memory will be left unallocated according to the setting 'memory.leftToOS' not taking into account heap memory 18:32:26.018 INFO com.orientechnologies - OrientDB auto-config DISKCACHE=20 083MB (heap=7 972MB os=31 881MB) 18:32:26.020 INFO c.o.o.c.e.l.OEngineLocalPaginated - System is started under an effective user : `user` 18:32:26.020 INFO c.o.o.c.e.l.OEngineLocalPaginated - Allocation of 305261 pages. 18:32:26.714 INFO c.o.o.c.s.m.ODirectMemoryStorage - Storage 'memory:cache' is created under OrientDB distribution : 3.0.37 - Veloce (build 6a0e4724c10d51a0b19700fca46da8e41ae006f5, branch UNKNOWN) 18:32:27.614 INFO org.jbake.template.ModelExtractors - register new extractors for document type: masterindex 18:32:27.615 INFO org.jbake.template.ModelExtractors - register new extractors for document type: tagsindex 18:32:27.615 INFO org.jbake.template.ModelExtractors - register new extractors for document type: sitemap 18:32:27.883 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/about.html]... : new 18:32:27.891 INFO org.jbake.parser.AsciidoctorEngine - Initializing Asciidoctor engine... 18:32:29.672 INFO org.jbake.parser.AsciidoctorEngine - Asciidoctor engine initialized. 18:32:29.811 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/fifth-post.adoc]... : new 18:32:29.816 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/first-post.html]... : new 18:32:29.896 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/fourth-post.adoc]... : new 18:32:29.995 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/second-post.md]... : new 18:32:30.029 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/third-post.adoc]... : new 18:32:30.030 INFO org.jbake.app.Crawler - Content detected: 18:32:30.030 INFO org.jbake.app.Crawler - Parsed 1 files of type: page 18:32:30.030 INFO org.jbake.app.Crawler - Parsed 5 files of type: post 18:32:30.126 INFO org.jbake.app.Renderer - Rendering archive [/home/user/VSCodeProjects/blog/out/site/jbake.dest/archive.html]... done! 18:32:30.132 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/about.html]... done! 18:32:30.143 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/fifth-post.html]... done! 18:32:30.146 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/fourth-post.html]... done! 18:32:30.149 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/third-post.html]... done! 18:32:30.152 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/second-post.html]... done! 18:32:30.156 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/first-post.html]... done! 18:32:30.182 INFO org.jbake.app.Renderer - Rendering feed [/home/user/VSCodeProjects/blog/out/site/jbake.dest/feed.xml]... done! 18:32:30.189 INFO org.jbake.app.Renderer - Rendering masterindex [/home/user/VSCodeProjects/blog/out/site/jbake.dest/index.html]... done! 18:32:30.199 INFO org.jbake.app.Renderer - Rendering sitemap [/home/user/VSCodeProjects/blog/out/site/jbake.dest/sitemap.xml]... done! 18:32:30.205 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/asciidoctor.css]... done! 18:32:30.206 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/base.css]... done! 18:32:30.206 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/bootstrap.min.css]... done! 18:32:30.206 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/prettify.css]... done! 18:32:30.207 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/favicon.ico]... done! 18:32:30.207 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/fonts/glyphicons-halflings-regular.eot]... done! 18:32:30.208 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/fonts/glyphicons-halflings-regular.svg]... done! 18:32:30.208 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/fonts/glyphicons-halflings-regular.ttf]... done! 18:32:30.208 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/fonts/glyphicons-halflings-regular.woff]... done! 18:32:30.209 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/img/beach.jpg]... done! 18:32:30.209 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/js/bootstrap.min.js]... done! 18:32:30.209 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/js/html5shiv.min.js]... done! 18:32:30.209 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/js/jquery-1.11.1.min.js]... done! 18:32:30.210 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/js/prettify.js]... done! 18:32:30.210 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/content/about/jbake_logo.png]... done! 18:32:30.210 INFO org.jbake.app.Oven - Baking finished! 18:32:30.210 INFO org.jbake.app.Oven - Baked 10 items in 4496ms [9/9] site.jbakeCopy Copying site from '/home/user/VSCodeProjects/blog/out/site/jbake.dest' to '/home/user/VSCodeProjects/tech4rd/docs' We can also invoke the jbakeCopy target passing it the /tmp destination path: ~/VSCodeProjects/blog$ ./mill -i site.jbakeCopy /tmp Output: [9/9] site.jbakeCopy Copying site from '/home/user/VSCodeProjects/blog/out/site/jbake.dest' to '/tmp/docs' To be able to deploy a site in Github pages, we need only commit and push the new content to the remote public website repository. The code snippet below shows the jbakeDeploy target that does this: def jbakeDeploy( args: String* ): Command[Unit] = T.command { val wasCopied = jbakeCopy(args:_*)() if (wasCopied.isDefined){ // Check if we are in a git repo val destination = wasCopied.get val repo = destination / ".git" val exists = os.exists(repo) && os.isDir(repo) T.ctx().log.info(s"pushSite: check if Git repo") val isGitRepoCommand = List("git", "rev-parse", "--is-inside-work-tree") val isGitRepoRes = os.proc(isGitRepoCommand) .call( cwd = destination, mergeErrIntoOut = true ) // Is it a repo? val out = isGitRepoRes.out.string.trim val isRepo = out == "true" if (exists && isRepo){ T.ctx().log.info(s"Git command at ${destination}") val addCommand = List("git", "add", ".") val message = if (args.length >=2) args(1) else "" val commitMessage = s"${LocalDateTime.now()}@$millSourcePath/build.sc/pushSite}: ${message}" T.ctx().log.info(s"pushSite: commit message = '$commitMessage'") val commitCommand = List("git", "commit", "-a", "-m", commitMessage) val pushCommand = List("git", "push") T.ctx().log.info(s"pushSite: add") val add = os.proc(addCommand) .call( cwd = destination ) T.ctx().log.info(s"pushSite: commit") val commit = os.proc(commitCommand) .call( cwd = destination ) T.ctx().log.info(s"pushSite: push") val push = os.proc(pushCommand) .call( cwd = destination ) } else { T.ctx().log.info(s"Git not found at ${destination}. No git commands executed.") } } } In the code snippet above, the jbakeCopy target is first invoked to ensure that the website's source is compiled and then copied to the public website repository. If the website's content was successfully generated and copied, then it checks to see if the destination folder is a valid Git repository by executing the Git command: git rev-parse --is-inside-work-tree If the destination folder is a valid Git repository, then it executes the Git commands add, commit and push. If the destination repository is correctly configured to use Github pages, then the website will be published and made available at the configured Github pages URL. Note that the website will take some time to be published. Here is an example of deploying the site via Github pages using the target above: $ cd /home/user/VSCodeProjects/blog $ ~/VSCodeProjects/blog$ ./mill -i site.jbakeDeploy Output of the jbakeCopy target command... Compiling /home/user/VSCodeProjects/blog/build.sc [7/10] site.jbake JBake v2.6.7 (2021-05-14 21:54:29[GMT+01:00]) [http://jbake.org] 18:31:23.772 INFO org.jbake.app.Oven - Baking has started... Warning: Nashorn engine is planned to be removed from a future JDK release 18:31:23.988 INFO c.o.common.jna.ONative - Detected limit of amount of simultaneously open files is 1048576, limit of open files for disk cache will be set to 523776 18:31:24.039 INFO c.o.common.jna.ONative - 33429823488 B/31881 MB/31 GB of physical memory were detected on machine 18:31:24.039 INFO c.o.common.jna.ONative - Soft memory limit for this process is set to -1 B/-1 MB/-1 GB 18:31:24.039 INFO c.o.common.jna.ONative - Hard memory limit for this process is set to -1 B/-1 MB/-1 GB 18:31:24.039 INFO c.o.common.jna.ONative - Path to 'memory' cgroup is '/user.slice/user-1000.slice/user@1000.service' 18:31:24.040 INFO c.o.common.jna.ONative - Mounting path for memory cgroup controller is '/sys/fs/cgroup/memory' 18:31:24.041 INFO c.o.common.jna.ONative - cgroup soft memory limit is 9223372036854771712 B/8796093022207 MB/8589934591 GB 18:31:24.041 INFO c.o.common.jna.ONative - cgroup hard memory limit is 9223372036854771712 B/8796093022207 MB/8589934591 GB 18:31:24.041 INFO c.o.common.jna.ONative - Detected memory limit for current process is 33429823488 B/31881 MB/31 GB 18:31:24.042 INFO c.o.o.c.e.OMemoryAndLocalPaginatedEnginesInitializer - JVM can use maximum 7972MB of heap memory 18:31:24.042 INFO c.o.o.c.e.OMemoryAndLocalPaginatedEnginesInitializer - Because OrientDB is running outside a container 12% of memory will be left unallocated according to the setting 'memory.leftToOS' not taking into account heap memory 18:31:24.043 INFO com.orientechnologies - OrientDB auto-config DISKCACHE=20 083MB (heap=7 972MB os=31 881MB) 18:31:24.044 INFO c.o.o.c.e.l.OEngineLocalPaginated - System is started under an effective user : `user` 18:31:24.045 INFO c.o.o.c.e.l.OEngineLocalPaginated - Allocation of 305261 pages. 18:31:24.761 INFO c.o.o.c.s.m.ODirectMemoryStorage - Storage 'memory:cache' is created under OrientDB distribution : 3.0.37 - Veloce (build 6a0e4724c10d51a0b19700fca46da8e41ae006f5, branch UNKNOWN) 18:31:25.770 INFO org.jbake.template.ModelExtractors - register new extractors for document type: masterindex 18:31:25.771 INFO org.jbake.template.ModelExtractors - register new extractors for document type: tagsindex 18:31:25.771 INFO org.jbake.template.ModelExtractors - register new extractors for document type: sitemap 18:31:25.960 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/about.html]... : new 18:31:25.970 INFO org.jbake.parser.AsciidoctorEngine - Initializing Asciidoctor engine... 18:31:27.877 INFO org.jbake.parser.AsciidoctorEngine - Asciidoctor engine initialized. 18:31:28.036 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/fifth-post.adoc]... : new 18:31:28.040 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/first-post.html]... : new 18:31:28.116 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/fourth-post.adoc]... : new 18:31:28.224 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/second-post.md]... : new 18:31:28.258 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/third-post.adoc]... : new 18:31:28.258 INFO org.jbake.app.Crawler - Content detected: 18:31:28.258 INFO org.jbake.app.Crawler - Parsed 1 files of type: page 18:31:28.258 INFO org.jbake.app.Crawler - Parsed 5 files of type: post 18:31:28.363 INFO org.jbake.app.Renderer - Rendering archive [/home/user/VSCodeProjects/blog/out/site/jbake.dest/archive.html]... done! 18:31:28.369 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/about.html]... done! 18:31:28.385 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/fifth-post.html]... done! 18:31:28.388 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/fourth-post.html]... done! 18:31:28.391 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/third-post.html]... done! 18:31:28.395 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/second-post.html]... done! 18:31:28.399 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/first-post.html]... done! 18:31:28.430 INFO org.jbake.app.Renderer - Rendering feed [/home/user/VSCodeProjects/blog/out/site/jbake.dest/feed.xml]... done! 18:31:28.436 INFO org.jbake.app.Renderer - Rendering masterindex [/home/user/VSCodeProjects/blog/out/site/jbake.dest/index.html]... done! 18:31:28.447 INFO org.jbake.app.Renderer - Rendering sitemap [/home/user/VSCodeProjects/blog/out/site/jbake.dest/sitemap.xml]... done! 18:31:28.451 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/asciidoctor.css]... done! 18:31:28.452 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/base.css]... done! 18:31:28.452 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/bootstrap.min.css]... done! 18:31:28.452 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/prettify.css]... done! 18:31:28.452 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/favicon.ico]... done! 18:31:28.452 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/fonts/glyphicons-halflings-regular.eot]... done! 18:31:28.453 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/fonts/glyphicons-halflings-regular.svg]... done! 18:31:28.453 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/fonts/glyphicons-halflings-regular.ttf]... done! 18:31:28.453 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/fonts/glyphicons-halflings-regular.woff]... done! 18:31:28.454 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/img/beach.jpg]... done! 18:31:28.454 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/js/bootstrap.min.js]... done! 18:31:28.454 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/js/html5shiv.min.js]... done! 18:31:28.455 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/js/jquery-1.11.1.min.js]... done! 18:31:28.455 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/js/prettify.js]... done! 18:31:28.456 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/content/about/jbake_logo.png]... done! 18:31:28.456 INFO org.jbake.app.Oven - Baking finished! 18:31:28.456 INFO org.jbake.app.Oven - Baked 10 items in 4685ms [9/10] site.jbakeCopy Copying site from '/home/user/VSCodeProjects/blog/out/site/jbake.dest' to '/home/user/VSCodeProjects/tech4rd/docs' [10/10] site.jbakeDeploy pushSite: check if Git repo Git command at /home/user/VSCodeProjects/tech4rd pushSite: commit message = '2022-05-18T18:31:28.698889@/home/user/VSCodeProjects/blog/site/build.sc/pushSite}: ' pushSite: add pushSite: commit pushSite: push Enumerating objects: 7, done. Counting objects: 100% (7/7), done. Delta compression using up to 12 threads Compressing objects: 100% (4/4), done. Writing objects: 100% (4/4), 415 bytes | 415.00 KiB/s, done. Total 4 (delta 3), reused 0 (delta 0) remote: Resolving deltas: 100% (3/3), completed with 3 local objects. To https://github.com/hmf/tech4rd.git 1386894..fe6d585 main -> main Just as in the case of the jbakeCopy target, we can also pass the destination path to the jbakeCopy target. Here is an example: ~/VSCodeProjects/blog$ ./mill -i site.jbakeDeploy /tmp And the output is: [9/10] site.jbakeCopy Copying site from '/home/user/VSCodeProjects/blog/out/site/jbake.dest' to '/tmp/docs' [10/10] site.jbakeDeploy pushSite: check if Git repo 1 targets failed site.jbakeDeploy os.SubprocessException: CommandResult 128 fatal: not a git repository (or any of the parent directories): .git os.proc.call(ProcessOps.scala:85) ammonite.$file.build$site$.$anonfun$jbakeDeploy$2(build.sc:94) scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18) Note that because the destination folder is not a valid Git repository, the target will fail. Using a different template JBake provides a set of example projects. These are usually stored in the JBake installation directory. The Mill JBake plugin downloads and places these in the project's "distribution" output directory. Here is a list of those files for the version of JBake we selected: ~$ ls -l /~/VSCodeProjects/blog/out/site/jbakeDistributionDir.dest/unpacked/jbake-2.6.7-bin/ total 3,3M drwxrwxr-x 2 user user 4,0K mai 18 18:33 bin -rw-rw-r-- 1 user user 299K mai 18 18:33 example_project_freemarker.zip -rw-rw-r-- 1 user user 2,1M mai 18 18:33 example_project_groovy-mte.zip -rw-rw-r-- 1 user user 299K mai 18 18:33 example_project_groovy.zip -rw-rw-r-- 1 user user 298K mai 18 18:33 example_project_jade.zip -rw-rw-r-- 1 user user 300K mai 18 18:33 example_project_thymeleaf.zip drwxrwxr-x 3 user user 4,0K mai 18 18:33 lib If you want to change these examples so that you can initialize a site using your own custom structure and templates, you need to extract, change and repack the content of these archives so that the jbakeInit Mill target can use them. When using Mill, this is not the best solution because JBake is installed for each project module you set up. You would have to repeat the process of changing the template archives again. A better alternative is to create and keep your site "theme" in a separate code repository and then automatically download and unpack the contents into the docs folder simply pointing to the URL of that repository. Here is an example of Benjamin Marwell providing the JBake Author template, which is a port of the Wordpress Author theme. Their are other such as: JBake Future Imperfect template JBake Clean Blog theme JBake Phlat theme Beautiful-JBake template Preparing one of these template or themes takes time and effort and the results may vary widely in terms of aesthetics and functionality. This is why I have opted to use an existing template. In particular, we will use the JBake Future Imperfect template because it has a pleasing aesthetic and is feature rich. It includes: Support for Discus comments Google analytics tracking Estimation of reading time Social links Customized Page not found - 404 URL Post featured images Feeds (JSON and RSS XML) To initialize the JBake site with the contents of the Git URL, the following jbakeGitTemplate target can be used: def jbakeGitTemplate( args: String* ): Command[Unit] = T.command { val srcDir = sources().head.path val source: String = if (args.size > 0) args(0) else gitTemplateURL() T.ctx().log.info(s"""jbakeGitTemplate: Git source at "${source}" """) val destination = build.millSourcePath T.ctx().log.info(s"jbakeGitTemplate: check if Git repo at $destination") val isGit = isGitRepo(destination) if (isGit) { if (os.exists(srcDir)){ T.ctx().log.info(s"""Git command at "${millSourcePath}" remove "$srcDir"""") os.remove.all(srcDir) os.remove(srcDir) } val relative = srcDir.relativeTo(millSourcePath).toString T.ctx().log.info(s"""Git clone command at "${millSourcePath}" with relative destination to "$relative"""") val cloneCommand = List("git", "clone", source, relative) val add = os.proc(cloneCommand) .call( cwd = millSourcePath ) } else { T.ctx().log.info(s"Git not found at ${destination}. No git commands executed.") } } This target is equivalent to a jbakeInit. It will delete all of the website's sources, so be careful. It first obtains the public Git URL from the command line parameter. If no URL is provided it defaults to the gitTemplateURL target shown below. You can set the default URL in your Mill script by overriding this target. def gitTemplateURL: T[String] = T { "https://github.com/manikmagar/jbake-future-imperfect-template.git" } To see the default URL that is set in the Mills script, execute the following command: ./mill -i show site.gitTemplateURL The jbakeGitTemplate then checks if the destination target is a git repository. If it is, then executes a git clone command that copies the remote repository's content into the Mill module's destination folder. In this running example the JBake template sources are placed in the following folder: home/user/VSCodeProjects/blog/site/src At this point you are ready to contribute content to the template and then bake, serve and/or deploy the website's content as previously described. The following is an example of initializing a JBake template by explicitly providing a Git repository URL: ~/VSCodeProjects/blog$ ./mill -i site.jbakeGitTemplate https://github.com/SiddheshRane/jbake-clean-blog-template And here is the output of the command (note the folders where the template's sources are placed): [3/3] site.jbakeGitTemplate jbakeGitTemplate: Git source at "https://github.com/SiddheshRane/jbake-clean-blog-template" jbakeGitTemplate: check if Git repo at /home/user/VSCodeProjects/blog Git command at "/home/user/VSCodeProjects/blog/site" remove "/home/user/VSCodeProjects/blog/site/src" Git clone command at "/home/user/VSCodeProjects/blog/site" with relative destination to "src" Cloning into 'src'... remote: Enumerating objects: 264, done. remote: Total 264 (delta 0), reused 0 (delta 0), pack-reused 264 Receiving objects: 100% (264/264), 3.51 MiB | 3.75 MiB/s, done. Resolving deltas: 100% (121/121), done. One can now serve and test the website as follows: ~/VSCodeProjects/blog$ ./mill -i site.jbakeServe Output of the site.jbakeServe target ... [8/8] site.jbakeServe JBake v2.6.7 (2021-05-14 21:54:29[GMT+01:00]) [http://jbake.org] 11:23:06.454 INFO org.jbake.app.Oven - Baking has started... Warning: Nashorn engine is planned to be removed from a future JDK release 11:23:06.681 INFO c.o.common.jna.ONative - Detected limit of amount of simultaneously open files is 1048576, limit of open files for disk cache will be set to 523776 11:23:06.736 INFO c.o.common.jna.ONative - 33429815296 B/31881 MB/31 GB of physical memory were detected on machine 11:23:06.736 INFO c.o.common.jna.ONative - Soft memory limit for this process is set to -1 B/-1 MB/-1 GB 11:23:06.736 INFO c.o.common.jna.ONative - Hard memory limit for this process is set to -1 B/-1 MB/-1 GB 11:23:06.736 INFO c.o.common.jna.ONative - Path to 'memory' cgroup is '/user.slice/user-1000.slice/user@1000.service' 11:23:06.737 INFO c.o.common.jna.ONative - Mounting path for memory cgroup controller is '/sys/fs/cgroup/memory' 11:23:06.737 INFO c.o.common.jna.ONative - cgroup soft memory limit is 9223372036854771712 B/8796093022207 MB/8589934591 GB 11:23:06.737 INFO c.o.common.jna.ONative - cgroup hard memory limit is 9223372036854771712 B/8796093022207 MB/8589934591 GB 11:23:06.738 INFO c.o.common.jna.ONative - Detected memory limit for current process is 33429815296 B/31881 MB/31 GB 11:23:06.738 INFO c.o.o.c.e.OMemoryAndLocalPaginatedEnginesInitializer - JVM can use maximum 7972MB of heap memory 11:23:06.738 INFO c.o.o.c.e.OMemoryAndLocalPaginatedEnginesInitializer - Because OrientDB is running outside a container 12% of memory will be left unallocated according to the setting 'memory.leftToOS' not taking into account heap memory 11:23:06.739 INFO com.orientechnologies - OrientDB auto-config DISKCACHE=20 083MB (heap=7 972MB os=31 881MB) 11:23:06.740 INFO c.o.o.c.e.l.OEngineLocalPaginated - System is started under an effective user : `user` 11:23:06.742 INFO c.o.o.c.e.l.OEngineLocalPaginated - Allocation of 305261 pages. 11:23:07.450 INFO c.o.o.c.s.m.ODirectMemoryStorage - Storage 'memory:cache' is created under OrientDB distribution : 3.0.37 - Veloce (build 6a0e4724c10d51a0b19700fca46da8e41ae006f5, branch UNKNOWN) 11:23:08.446 INFO org.jbake.template.ModelExtractors - register new extractors for document type: masterindex 11:23:08.448 INFO org.jbake.template.ModelExtractors - register new extractors for document type: sitemap 11:23:08.448 INFO org.jbake.template.ModelExtractors - register new extractors for document type: tagsindex 11:23:08.713 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/about.html]... : new 11:23:08.719 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/first-post.html]... : new 11:23:08.733 INFO org.jbake.parser.AsciidoctorEngine - Initializing Asciidoctor engine... 11:23:10.469 INFO org.jbake.parser.AsciidoctorEngine - Asciidoctor engine initialized. 11:23:10.668 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/fourth-post.adoc]... : new 11:23:10.804 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/second-post.md]... : new 11:23:10.851 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/third-post.adoc]... : new 11:23:10.851 INFO org.jbake.app.Crawler - Content detected: 11:23:10.851 INFO org.jbake.app.Crawler - Parsed 1 files of type: page 11:23:10.851 INFO org.jbake.app.Crawler - Parsed 4 files of type: post 11:23:11.045 INFO org.jbake.app.Renderer - Rendering archive [/home/user/VSCodeProjects/blog/out/site/jbake.dest/archive.html]... done! 11:23:11.064 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/about.html]... done! 11:23:11.097 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/fourth-post.html]... done! 11:23:11.105 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/third-post.html]... done! 11:23:11.112 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/second-post.html]... done! 11:23:11.120 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/first-post.html]... done! 11:23:11.151 INFO org.jbake.app.Renderer - Rendering feed [/home/user/VSCodeProjects/blog/out/site/jbake.dest/feed.xml]... done! 11:23:11.171 INFO org.jbake.app.Renderer - Rendering masterindex [/home/user/VSCodeProjects/blog/out/site/jbake.dest/index.html]... done! 11:23:11.183 INFO org.jbake.app.Renderer - Rendering sitemap [/home/user/VSCodeProjects/blog/out/site/jbake.dest/sitemap.xml]... done! 11:23:11.210 INFO org.jbake.app.Renderer - Rendering tag [/home/user/VSCodeProjects/blog/out/site/jbake.dest/tags/asciidoc.html]... done! 11:23:11.219 INFO org.jbake.app.Renderer - Rendering tag [/home/user/VSCodeProjects/blog/out/site/jbake.dest/tags/blog.html]... done! 11:23:11.222 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/asciidoctor.css]... done! 11:23:11.222 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/clean-blog.css]... done! 11:23:11.223 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/clean-blog.min.css]... done! 11:23:11.223 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/coderay.css]... done! 11:23:11.223 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/favicon.png]... done! 11:23:11.223 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/img/archive-cover.jpg]... done! 11:23:11.225 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/img/clean-blog-share-card.png]... done! 11:23:11.225 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/img/grand-canyon.jpg]... done! 11:23:11.225 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/img/index-cover.jpg]... done! 11:23:11.226 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/img/jbake-logo.png]... done! 11:23:11.226 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/img/jekyll-logo.png]... done! 11:23:11.226 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/img/page-cover.jpg]... done! 11:23:11.226 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/img/tags-cover.jpg]... done! 11:23:11.227 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/js/clean-blog.js]... done! 11:23:11.227 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/js/clean-blog.min.js]... done! 11:23:11.227 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/bootstrap/css/bootstrap.css]... done! 11:23:11.228 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/bootstrap/css/bootstrap.min.css]... done! 11:23:11.228 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/bootstrap/fonts/glyphicons-halflings-regular.eot]... done! 11:23:11.229 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/bootstrap/fonts/glyphicons-halflings-regular.svg]... done! 11:23:11.229 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/bootstrap/fonts/glyphicons-halflings-regular.ttf]... done! 11:23:11.229 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff]... done! 11:23:11.230 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff2]... done! 11:23:11.230 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/bootstrap/js/bootstrap.js]... done! 11:23:11.230 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/bootstrap/js/bootstrap.min.js]... done! 11:23:11.231 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/css/font-awesome.css]... done! 11:23:11.231 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/css/font-awesome.min.css]... done! 11:23:11.232 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/fonts/FontAwesome.otf]... done! 11:23:11.232 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/fonts/fontawesome-webfont.eot]... done! 11:23:11.232 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/fonts/fontawesome-webfont.svg]... done! 11:23:11.233 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/fonts/fontawesome-webfont.ttf]... done! 11:23:11.233 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/fonts/fontawesome-webfont.woff]... done! 11:23:11.234 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/fonts/fontawesome-webfont.woff2]... done! 11:23:11.234 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/animated.less]... done! 11:23:11.235 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/bordered-pulled.less]... done! 11:23:11.235 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/core.less]... done! 11:23:11.235 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/fixed-width.less]... done! 11:23:11.235 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/font-awesome.less]... done! 11:23:11.235 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/icons.less]... done! 11:23:11.235 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/larger.less]... done! 11:23:11.236 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/list.less]... done! 11:23:11.236 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/mixins.less]... done! 11:23:11.236 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/path.less]... done! 11:23:11.236 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/rotated-flipped.less]... done! 11:23:11.236 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/screen-reader.less]... done! 11:23:11.237 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/stacked.less]... done! 11:23:11.237 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/variables.less]... done! 11:23:11.237 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_animated.scss]... done! 11:23:11.238 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_bordered-pulled.scss]... done! 11:23:11.238 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_core.scss]... done! 11:23:11.238 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_fixed-width.scss]... done! 11:23:11.238 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_icons.scss]... done! 11:23:11.238 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_larger.scss]... done! 11:23:11.239 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_list.scss]... done! 11:23:11.239 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_mixins.scss]... done! 11:23:11.239 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_path.scss]... done! 11:23:11.239 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_rotated-flipped.scss]... done! 11:23:11.239 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_screen-reader.scss]... done! 11:23:11.240 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_stacked.scss]... done! 11:23:11.240 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_variables.scss]... done! 11:23:11.240 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/font-awesome.scss]... done! 11:23:11.241 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/jquery/jquery.js]... done! 11:23:11.241 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/jquery/jquery.min.js]... done! 11:23:11.242 INFO org.jbake.app.Oven - Baking finished! 11:23:11.242 INFO org.jbake.app.Oven - Baked 11 items in 4788ms 11:23:11.242 INFO c.o.orient.core.db.OrientDBEmbedded - - shutdown storage: cache... 11:23:11.282 INFO org.jbake.launcher.BakeWatcher - Watching for (content, template, asset) changes in [/home/user/VSCodeProjects/blog/site/src] 11:23:11.348 INFO org.jbake.launcher.JettyServer - Serving out contents of: [/home/user/VSCodeProjects/blog/out/site/jbake.dest] on http://localhost:8820/ 11:23:11.348 INFO org.jbake.launcher.JettyServer - (To stop server hit CTRL-C) If you point your browser to the local URL http://localhost:8820/, you should see the website's content similar to what is shown below: When you are ready to publish the website's content to the remote host, execute the following command: ~/VSCodeProjects/blog$ ./mill -i site.jbakeDeploy Output of the site.jbakeDeploy target ... [7/10] site.jbake JBake v2.6.7 (2021-05-14 21:54:29[GMT+01:00]) [http://jbake.org] 11:21:44.329 INFO org.jbake.app.Oven - Baking has started... Warning: Nashorn engine is planned to be removed from a future JDK release 11:21:44.564 INFO c.o.common.jna.ONative - Detected limit of amount of simultaneously open files is 1048576, limit of open files for disk cache will be set to 523776 11:21:44.614 INFO c.o.common.jna.ONative - 33429815296 B/31881 MB/31 GB of physical memory were detected on machine 11:21:44.614 INFO c.o.common.jna.ONative - Soft memory limit for this process is set to -1 B/-1 MB/-1 GB 11:21:44.614 INFO c.o.common.jna.ONative - Hard memory limit for this process is set to -1 B/-1 MB/-1 GB 11:21:44.614 INFO c.o.common.jna.ONative - Path to 'memory' cgroup is '/user.slice/user-1000.slice/user@1000.service' 11:21:44.615 INFO c.o.common.jna.ONative - Mounting path for memory cgroup controller is '/sys/fs/cgroup/memory' 11:21:44.615 INFO c.o.common.jna.ONative - cgroup soft memory limit is 9223372036854771712 B/8796093022207 MB/8589934591 GB 11:21:44.615 INFO c.o.common.jna.ONative - cgroup hard memory limit is 9223372036854771712 B/8796093022207 MB/8589934591 GB 11:21:44.615 INFO c.o.common.jna.ONative - Detected memory limit for current process is 33429815296 B/31881 MB/31 GB 11:21:44.616 INFO c.o.o.c.e.OMemoryAndLocalPaginatedEnginesInitializer - JVM can use maximum 7972MB of heap memory 11:21:44.616 INFO c.o.o.c.e.OMemoryAndLocalPaginatedEnginesInitializer - Because OrientDB is running outside a container 12% of memory will be left unallocated according to the setting 'memory.leftToOS' not taking into account heap memory 11:21:44.616 INFO com.orientechnologies - OrientDB auto-config DISKCACHE=20 083MB (heap=7 972MB os=31 881MB) 11:21:44.617 INFO c.o.o.c.e.l.OEngineLocalPaginated - System is started under an effective user : `user` 11:21:44.618 INFO c.o.o.c.e.l.OEngineLocalPaginated - Allocation of 305261 pages. 11:21:45.325 INFO c.o.o.c.s.m.ODirectMemoryStorage - Storage 'memory:cache' is created under OrientDB distribution : 3.0.37 - Veloce (build 6a0e4724c10d51a0b19700fca46da8e41ae006f5, branch UNKNOWN) 11:21:46.257 INFO org.jbake.template.ModelExtractors - register new extractors for document type: masterindex 11:21:46.258 INFO org.jbake.template.ModelExtractors - register new extractors for document type: sitemap 11:21:46.258 INFO org.jbake.template.ModelExtractors - register new extractors for document type: tagsindex 11:21:46.477 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/about.html]... : new 11:21:46.484 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/first-post.html]... : new 11:21:46.500 INFO org.jbake.parser.AsciidoctorEngine - Initializing Asciidoctor engine... 11:21:48.272 INFO org.jbake.parser.AsciidoctorEngine - Asciidoctor engine initialized. 11:21:48.426 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/fourth-post.adoc]... : new 11:21:48.525 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/second-post.md]... : new 11:21:48.556 INFO org.jbake.app.Crawler - Processing [/home/user/VSCodeProjects/blog/site/src/content/blog/2013/third-post.adoc]... : new 11:21:48.556 INFO org.jbake.app.Crawler - Content detected: 11:21:48.556 INFO org.jbake.app.Crawler - Parsed 1 files of type: page 11:21:48.556 INFO org.jbake.app.Crawler - Parsed 4 files of type: post 11:21:48.748 INFO org.jbake.app.Renderer - Rendering archive [/home/user/VSCodeProjects/blog/out/site/jbake.dest/archive.html]... done! 11:21:48.767 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/about.html]... done! 11:21:48.802 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/fourth-post.html]... done! 11:21:48.813 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/third-post.html]... done! 11:21:48.823 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/second-post.html]... done! 11:21:48.832 INFO org.jbake.app.Renderer - Rendering [/home/user/VSCodeProjects/blog/out/site/jbake.dest/blog/2013/first-post.html]... done! 11:21:48.870 INFO org.jbake.app.Renderer - Rendering feed [/home/user/VSCodeProjects/blog/out/site/jbake.dest/feed.xml]... done! 11:21:48.888 INFO org.jbake.app.Renderer - Rendering masterindex [/home/user/VSCodeProjects/blog/out/site/jbake.dest/index.html]... done! 11:21:48.900 INFO org.jbake.app.Renderer - Rendering sitemap [/home/user/VSCodeProjects/blog/out/site/jbake.dest/sitemap.xml]... done! 11:21:48.924 INFO org.jbake.app.Renderer - Rendering tag [/home/user/VSCodeProjects/blog/out/site/jbake.dest/tags/asciidoc.html]... done! 11:21:48.932 INFO org.jbake.app.Renderer - Rendering tag [/home/user/VSCodeProjects/blog/out/site/jbake.dest/tags/blog.html]... done! 11:21:48.936 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/asciidoctor.css]... done! 11:21:48.936 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/clean-blog.css]... done! 11:21:48.937 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/clean-blog.min.css]... done! 11:21:48.937 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/css/coderay.css]... done! 11:21:48.937 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/favicon.png]... done! 11:21:48.938 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/img/archive-cover.jpg]... done! 11:21:48.938 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/img/clean-blog-share-card.png]... done! 11:21:48.939 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/img/grand-canyon.jpg]... done! 11:21:48.939 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/img/index-cover.jpg]... done! 11:21:48.939 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/img/jbake-logo.png]... done! 11:21:48.939 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/img/jekyll-logo.png]... done! 11:21:48.940 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/img/page-cover.jpg]... done! 11:21:48.940 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/img/tags-cover.jpg]... done! 11:21:48.940 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/js/clean-blog.js]... done! 11:21:48.941 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/js/clean-blog.min.js]... done! 11:21:48.941 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/bootstrap/css/bootstrap.css]... done! 11:21:48.941 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/bootstrap/css/bootstrap.min.css]... done! 11:21:48.942 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/bootstrap/fonts/glyphicons-halflings-regular.eot]... done! 11:21:48.942 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/bootstrap/fonts/glyphicons-halflings-regular.svg]... done! 11:21:48.943 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/bootstrap/fonts/glyphicons-halflings-regular.ttf]... done! 11:21:48.943 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff]... done! 11:21:48.943 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff2]... done! 11:21:48.944 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/bootstrap/js/bootstrap.js]... done! 11:21:48.944 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/bootstrap/js/bootstrap.min.js]... done! 11:21:48.944 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/css/font-awesome.css]... done! 11:21:48.945 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/css/font-awesome.min.css]... done! 11:21:48.945 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/fonts/FontAwesome.otf]... done! 11:21:48.945 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/fonts/fontawesome-webfont.eot]... done! 11:21:48.946 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/fonts/fontawesome-webfont.svg]... done! 11:21:48.946 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/fonts/fontawesome-webfont.ttf]... done! 11:21:48.947 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/fonts/fontawesome-webfont.woff]... done! 11:21:48.947 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/fonts/fontawesome-webfont.woff2]... done! 11:21:48.947 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/animated.less]... done! 11:21:48.948 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/bordered-pulled.less]... done! 11:21:48.948 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/core.less]... done! 11:21:48.948 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/fixed-width.less]... done! 11:21:48.948 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/font-awesome.less]... done! 11:21:48.948 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/icons.less]... done! 11:21:48.949 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/larger.less]... done! 11:21:48.949 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/list.less]... done! 11:21:48.949 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/mixins.less]... done! 11:21:48.949 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/path.less]... done! 11:21:48.949 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/rotated-flipped.less]... done! 11:21:48.950 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/screen-reader.less]... done! 11:21:48.950 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/stacked.less]... done! 11:21:48.950 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/less/variables.less]... done! 11:21:48.951 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_animated.scss]... done! 11:21:48.951 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_bordered-pulled.scss]... done! 11:21:48.951 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_core.scss]... done! 11:21:48.951 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_fixed-width.scss]... done! 11:21:48.951 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_icons.scss]... done! 11:21:48.952 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_larger.scss]... done! 11:21:48.952 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_list.scss]... done! 11:21:48.952 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_mixins.scss]... done! 11:21:48.952 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_path.scss]... done! 11:21:48.952 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_rotated-flipped.scss]... done! 11:21:48.953 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_screen-reader.scss]... done! 11:21:48.953 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_stacked.scss]... done! 11:21:48.953 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/_variables.scss]... done! 11:21:48.953 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/font-awesome/scss/font-awesome.scss]... done! 11:21:48.954 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/jquery/jquery.js]... done! 11:21:48.954 INFO org.jbake.app.Asset - Copying [/home/user/VSCodeProjects/blog/site/src/assets/vendor/jquery/jquery.min.js]... done! 11:21:48.954 INFO org.jbake.app.Oven - Baking finished! 11:21:48.954 INFO org.jbake.app.Oven - Baked 11 items in 4626ms [9/10] site.jbakeCopy Copying site from '/home/user/VSCodeProjects/blog/out/site/jbake.dest' to '/home/user/VSCodeProjects/tech4rd/docs' [10/10] site.jbakeDeploy pushSite: check if Git repo Git command at /home/user/VSCodeProjects/tech4rd pushSite: commit message = '2022-05-21T11:21:49.241238@/home/user/VSCodeProjects/blog/site/build.sc/pushSite}: ' pushSite: add pushSite: commit pushSite: push Enumerating objects: 111, done. Counting objects: 100% (111/111), done. Delta compression using up to 12 threads Compressing objects: 100% (91/91), done. Writing objects: 100% (92/92), 2.34 MiB | 4.51 MiB/s, done. Total 92 (delta 14), reused 0 (delta 0) remote: Resolving deltas: 100% (14/14), completed with 3 local objects. To https://github.com/user/tech4rd.git 82fbf46..cc57fd4 main -> main If you point your browser to the Github pages URL, you should see the website's content similar to what is shown below: Conclusion This concludes the first part of this series. You should now be able to publish a website using Github pages. In addition to this and with the help of the Mill script, you can now automate the generation of the website's content from your own private repository and publish it with a single command. In the next part we will set up the JBake Future Imperfect template and publish a first article. References Markdown AsciiDoc site AsciiDoc Wikipedia ReStructuredText Freemarker ThymeLeaf Google Analytics MathJax MathJS KaTex Mermaid-Js Flowchart.js ChartJS Plotly Chartist-Js RawGraphs.io d3js c3js nvd3 Mill Github Mill Github pages FeatherIcons IonIcons FontAwesome Tabler css.gg Docusaurus.io Docusaurus Github Jekyll Jekyll Github JBake github JBake Laika Laika Github Scala-lang docs Scala3 ScalaDoc Scala3 ScalaDoc Guide Scala3 ScalaDoc Usage Scala3/Dotty - ScalaDocs github Javadoc Sbt-site Github Sbt-site sphinx-doc Pamflet Pamflet Github Nanoc GitBook Paradox Github Paradox GoHugo AsciiDoctor Mill Build tool Mill Docusaurus plugin Mill JBake plugin Mill MDoc plugin MDoc MDoc in Github Mill JBake plugin in Github Github pages Gitlab pages Github Flavoured Markdown Gitlab Flavoured Markdown John Gruber’s canonical description of Markdown’s syntax Commonmark variant Markdown Guide Markdown guide extended-syntax R Markdown variant JBake documentation Ammonite Coursier JBake Author template See for example information provided for the Gitlab pages and the Github pages. ↩ Twitter Google+ Facebook Reddit LinkedIn StumbleUpon Email