mdBook/continuous-integration.html

318 lines
23 KiB
HTML

<!DOCTYPE HTML>
<html lang="en" class="light" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Continuous Integration - mdBook Documentation</title>
<!-- Custom HTML head -->
<meta name="description" content="Create book from markdown files. Like Gitbook but implemented in Rust">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('light')
html.classList.add(theme);
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var body = document.querySelector('body');
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded affix "><a href="index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">User Guide</li><li class="chapter-item expanded "><a href="guide/installation.html"><strong aria-hidden="true">1.</strong> Installation</a></li><li class="chapter-item expanded "><a href="guide/reading.html"><strong aria-hidden="true">2.</strong> Reading Books</a></li><li class="chapter-item expanded "><a href="guide/creating.html"><strong aria-hidden="true">3.</strong> Creating a Book</a></li><li class="chapter-item expanded affix "><li class="part-title">Reference Guide</li><li class="chapter-item expanded "><a href="cli/index.html"><strong aria-hidden="true">4.</strong> Command Line Tool</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="cli/init.html"><strong aria-hidden="true">4.1.</strong> init</a></li><li class="chapter-item expanded "><a href="cli/build.html"><strong aria-hidden="true">4.2.</strong> build</a></li><li class="chapter-item expanded "><a href="cli/watch.html"><strong aria-hidden="true">4.3.</strong> watch</a></li><li class="chapter-item expanded "><a href="cli/serve.html"><strong aria-hidden="true">4.4.</strong> serve</a></li><li class="chapter-item expanded "><a href="cli/test.html"><strong aria-hidden="true">4.5.</strong> test</a></li><li class="chapter-item expanded "><a href="cli/clean.html"><strong aria-hidden="true">4.6.</strong> clean</a></li><li class="chapter-item expanded "><a href="cli/completions.html"><strong aria-hidden="true">4.7.</strong> completions</a></li></ol></li><li class="chapter-item expanded "><a href="format/index.html"><strong aria-hidden="true">5.</strong> Format</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="format/summary.html"><strong aria-hidden="true">5.1.</strong> SUMMARY.md</a></li><li><ol class="section"><li class="chapter-item expanded "><div><strong aria-hidden="true">5.1.1.</strong> Draft chapter</div></li></ol></li><li class="chapter-item expanded "><a href="format/configuration/index.html"><strong aria-hidden="true">5.2.</strong> Configuration</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="format/configuration/general.html"><strong aria-hidden="true">5.2.1.</strong> General</a></li><li class="chapter-item expanded "><a href="format/configuration/preprocessors.html"><strong aria-hidden="true">5.2.2.</strong> Preprocessors</a></li><li class="chapter-item expanded "><a href="format/configuration/renderers.html"><strong aria-hidden="true">5.2.3.</strong> Renderers</a></li><li class="chapter-item expanded "><a href="format/configuration/environment-variables.html"><strong aria-hidden="true">5.2.4.</strong> Environment Variables</a></li></ol></li><li class="chapter-item expanded "><a href="format/theme/index.html"><strong aria-hidden="true">5.3.</strong> Theme</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="format/theme/index-hbs.html"><strong aria-hidden="true">5.3.1.</strong> index.hbs</a></li><li class="chapter-item expanded "><a href="format/theme/syntax-highlighting.html"><strong aria-hidden="true">5.3.2.</strong> Syntax highlighting</a></li><li class="chapter-item expanded "><a href="format/theme/editor.html"><strong aria-hidden="true">5.3.3.</strong> Editor</a></li></ol></li><li class="chapter-item expanded "><a href="format/mathjax.html"><strong aria-hidden="true">5.4.</strong> MathJax Support</a></li><li class="chapter-item expanded "><a href="format/mdbook.html"><strong aria-hidden="true">5.5.</strong> mdBook-specific features</a></li><li class="chapter-item expanded "><a href="format/markdown.html"><strong aria-hidden="true">5.6.</strong> Markdown</a></li></ol></li><li class="chapter-item expanded "><a href="continuous-integration.html" class="active"><strong aria-hidden="true">6.</strong> Continuous Integration</a></li><li class="chapter-item expanded "><a href="for_developers/index.html"><strong aria-hidden="true">7.</strong> For Developers</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="for_developers/preprocessors.html"><strong aria-hidden="true">7.1.</strong> Preprocessors</a></li><li class="chapter-item expanded "><a href="for_developers/backends.html"><strong aria-hidden="true">7.2.</strong> Alternative Backends</a></li><li class="spacer"></li></ol></li><li class="chapter-item expanded "><a href="misc/contributors.html">Contributors</a></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<!-- Track and set sidebar scroll position -->
<script>
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
</script>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">mdBook Documentation</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/rust-lang/mdBook/tree/master/guide" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://github.com/rust-lang/mdBook/edit/master/guide/src/continuous-integration.md" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="running-mdbook-in-continuous-integration"><a class="header" href="#running-mdbook-in-continuous-integration">Running <code>mdbook</code> in Continuous Integration</a></h1>
<p>There are a variety of services such as <a href="https://docs.github.com/en/actions">GitHub Actions</a> or <a href="https://docs.gitlab.com/ee/ci/">GitLab CI/CD</a> which can be used to test and deploy your book automatically.</p>
<p>The following provides some general guidelines on how to configure your service to run mdBook.
Specific recipes can be found at the <a href="https://github.com/rust-lang/mdBook/wiki/Automated-Deployment">Automated Deployment</a> wiki page.</p>
<h2 id="installing-mdbook"><a class="header" href="#installing-mdbook">Installing mdBook</a></h2>
<p>There are several different strategies for installing mdBook.
The particular method depends on your needs and preferences.</p>
<h3 id="pre-compiled-binaries"><a class="header" href="#pre-compiled-binaries">Pre-compiled binaries</a></h3>
<p>Perhaps the easiest method is to use the pre-compiled binaries found on the <a href="https://github.com/rust-lang/mdBook/releases">GitHub Releases page</a>.
A simple approach would be to use the popular <code>curl</code> CLI tool to download the executable:</p>
<pre><code class="language-sh">mkdir bin
curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.37/mdbook-v0.4.37-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin
bin/mdbook build
</code></pre>
<p>Some considerations for this approach:</p>
<ul>
<li>This is relatively fast, and does not necessarily require dealing with caching.</li>
<li>This does not require installing Rust.</li>
<li>Specifying a specific URL means you have to manually update your script to get a new version.
This may be a benefit if you want to lock to a specific version.
However, some users prefer to automatically get a newer version when they are published.</li>
<li>You are reliant on the GitHub CDN being available.</li>
</ul>
<h3 id="building-from-source"><a class="header" href="#building-from-source">Building from source</a></h3>
<p>Building from source will require having Rust installed.
Some services have Rust pre-installed, but if your service does not, you will need to add a step to install it.</p>
<p>After Rust is installed, <code>cargo install</code> can be used to build and install mdBook.
We recommend using a SemVer version specifier so that you get the latest <strong>non-breaking</strong> version of mdBook.
For example:</p>
<pre><code class="language-sh">cargo install mdbook --no-default-features --features search --vers "^0.4" --locked
</code></pre>
<p>This includes several recommended options:</p>
<ul>
<li><code>--no-default-features</code> — Disables features like the HTTP server used by <code>mdbook serve</code> that is likely not needed on CI.
This will speed up the build time significantly.</li>
<li><code>--features search</code> — Disabling default features means you should then manually enable features that you want, such as the built-in <a href="guide/reading.html#search">search</a> capability.</li>
<li><code>--vers "^0.4"</code> — This will install the most recent version of the <code>0.4</code> series.
However, versions after like <code>0.5.0</code> won't be installed, as they may break your build.
Cargo will automatically upgrade mdBook if you have an older version already installed.</li>
<li><code>--locked</code> — This will use the dependencies that were used when mdBook was released.
Without <code>--locked</code>, it will use the latest version of all dependencies, which may include some fixes since the last release, but may also (rarely) cause build problems.</li>
</ul>
<p>You will likely want to investigate caching options, as building mdBook can be somewhat slow.</p>
<h2 id="running-tests"><a class="header" href="#running-tests">Running tests</a></h2>
<p>You may want to run tests using <a href="cli/test.html"><code>mdbook test</code></a> every time you push a change or create a pull request.
This can be used to validate Rust code examples in the book.</p>
<p>This will require having Rust installed.
Some services have Rust pre-installed, but if your service does not, you will need to add a step to install it.</p>
<p>Other than making sure the appropriate version of Rust is installed, there's not much more than just running <code>mdbook test</code> from the book directory.</p>
<p>You may also want to consider running other kinds of tests, like <a href="https://github.com/Michael-F-Bryan/mdbook-linkcheck#continuous-integration">mdbook-linkcheck</a> which will check for broken links.
Or if you have your own style checks, spell checker, or any other tests it might be good to run them in CI.</p>
<h2 id="deploying"><a class="header" href="#deploying">Deploying</a></h2>
<p>You may want to automatically deploy your book.
Some may want to do this every time a change is pushed, and others may want to only deploy when a specific release is tagged.</p>
<p>You'll also need to understand the specifics on how to push a change to your web service.
For example, <a href="https://docs.github.com/en/pages">GitHub Pages</a> just requires committing the output onto a specific git branch.
Other services may require using something like SSH to connect to a remote server.</p>
<p>The basic outline is that you need to run <code>mdbook build</code> to generate the output, and then transfer the files (which are in the <code>book</code> directory) to the correct location.</p>
<p>You may then want to consider if you need to invalidate any caches on your web service.</p>
<p>See the <a href="https://github.com/rust-lang/mdBook/wiki/Automated-Deployment">Automated Deployment</a> wiki page for examples of various different services.</p>
<h3 id="404-handling"><a class="header" href="#404-handling">404 handling</a></h3>
<p>mdBook automatically generates a 404 page to be used for broken links.
The default output is a file named <code>404.html</code> at the root of the book.
Some services like <a href="https://docs.github.com/en/pages">GitHub Pages</a> will automatically use this page for broken links.
For other services, you may want to consider configuring the web server to use this page as it will provide the reader navigation to get back to the book.</p>
<p>If your book is not deployed at the root of the domain, then you should set the <a href="format/configuration/renderers.html#html-renderer-options"><code>output.html.site-url</code></a> setting so that the 404 page works correctly.
It needs to know where the book is deployed in order to load the static files (like CSS) correctly.
For example, this guide is deployed at <a href="https://rust-lang.github.io/mdBook/">https://rust-lang.github.io/mdBook/</a>, and the <code>site-url</code> setting is configured like this:</p>
<pre><code class="language-toml"># book.toml
[output.html]
site-url = "/mdBook/"
</code></pre>
<p>You can customize the look of the 404 page by creating a file named <code>src/404.md</code> in your book.
If you want to use a different filename, you can set <a href="format/configuration/renderers.html#html-renderer-options"><code>output.html.input-404</code></a> to a different filename.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="format/markdown.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="for_developers/index.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="format/markdown.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="for_developers/index.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_line_numbers = true;
</script>
<script>
window.playground_copyable = true;
</script>
<script src="ace.js"></script>
<script src="editor.js"></script>
<script src="mode-rust.js"></script>
<script src="theme-dawn.js"></script>
<script src="theme-tomorrow_night.js"></script>
<script src="elasticlunr.min.js"></script>
<script src="mark.min.js"></script>
<script src="searcher.js"></script>
<script src="clipboard.min.js"></script>
<script src="highlight.js"></script>
<script src="book.js"></script>
<!-- Custom JS scripts -->
</div>
</body>
</html>