This is a simple guide on how to best build your documentation in Julia v1.0 if you are using
The old way
If you are using
Documenter you probably have something like the following in your
.travis.yml file for building your documentation:
after_success: - julia -e 'Pkg.add("Documenter")' - julia -e 'cd(Pkg.dir("PACKAGE_NAME")); include(joinpath("docs", "make.jl"))'
Why is this bad? Here are some reasons:
- There is no good way to add doc-build dependencies, you have to add them manually (like we
- Code in the
after_success:part of the build does not fail the build. This makes it difficult to verify that (i) the doc build works and (ii) that doctest etc. still passes. For this reason some package have chosen to build the docs as part of the test suite instead.
- Doc building runs in the global environment, and is thus affected by the surroundings.
So, maybe we can use this new
Pkg thing, that apparently should solve all our problems. Absolutely!
The new way
In Julia v1.0 we can instead use a designated doc-build project with a
Project.toml in the
docs/ directory. The project includes
Documenter and all your other doc-build dependencies. If
Documenter is the only dependency, then the
Project.toml file should include the following:
[deps] Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" [compat] Documenter = "~0.19"
Here we also added a compatibility constraint for
Documenter, since I happen to know that
Documenter 0.20 will break everything.
Instead of creating the
Project.toml file manually we could have started Julia with
julia --project=docs/ (alternatively just start Julia and then
using Pkg; Pkg.activate("docs")) and then used the
Pkg REPL to
add our doc-build dependencies.
Next we need to configure the
.travis.yml to use this project. For this we will utilize Travis Build Stages that have just been released (see https://docs.travis-ci.com/user/build-stages). Add the following to your
jobs: include: - stage: "Documentation" julia: 1.0 os: linux script: - julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()' - julia --project=docs/ docs/make.jl after_success: skip
This adds a new build stage, called
Documentation, that will run after the default
test stage. It will look something like this. The
os: entries control from which worker we build the docs, for example Julia
linux. What happens on the three lines in the
- The first line
Pkg.instantiate()s the project, meaning that
Documenterand the other dependencies will be installed.
- The second line adds our package to the doc-build environment.
- The third line builds the docs.
Lastly, commit the files (the
Manifest.toml can be
.gitignored) and push!
Why is this better?
- Using a custom docs projects gives full control over the environment where the docs build.
- We can have documentation dependencies.
- A failed doc build now fails CI.
In my opinion this is a pretty nice example of how to utilize the new
If you need some inspiration, have a look at the following packages that already uses projects and build stages for doc-building:
Make sure that the
Documenter.deploydocsmatch the configuration you define for the build stage in
.travis.yml. Note that this is something that will change in the next Documenter release, where the
osarguments are removed and the deployment is essentially governed by the
.travis.ymlconfiguration. So the annoyance of keeping those in sync is temporary. EDIT: This does not apply to Documenter v0.20.
If you are using doctests, you will run into https://github.com/JuliaLang/julia/pull/28625 (you will see something like
ERROR: LoadError: ArgumentError: Package Foo not found in current path) which is a bug in Julia
v1.0(but fixed on
nightlyand the upcoming Julia
v1.0.1). You can add the following lines at the top of
docs/make.jlto workaround it:
# Workaround for JuliaLang/julia/pull/28625 if Base.HOME_PROJECT !== nothing Base.HOME_PROJECT = abspath(Base.HOME_PROJECT) end
Feel free to ping me (
@fredrikekre) for any questions from your PRs. Happy upgrading!