# How Documenter makes docs for different versions?

**URL:** <https://discourse.julialang.org/t/how-documenter-makes-docs-for-different-versions/22445>\
**Category:** Offtopic\
**Tags:** documenter\
**Created:** [March 28, 2019, 8:59am UTC](https://discourse.julialang.org/t/how-documenter-makes-docs-for-different-versions/22445 "2019-03-28T08:59:28Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![cserteGT3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/csertegt3/32/8283_2.png) [@cserteGT3](https://discourse.julialang.org/u/cserteGT3)\
**Post date:** [March 28, 2019, 8:59am UTC](https://discourse.julialang.org/t/how-documenter-makes-docs-for-different-versions/22445/1 "2019-03-28T08:59:28Z")

</div>

I’m working on a small project (not julia related), that needs documentation. I really like the sites that Documenter.jl builds, particularly that I can see the docs of different versions (and the master branch). I would like to reproduce this behavior. I considered mkdocs but I’m not against using Documenter.jl for bulding the site.  
We don’t have any CI tool set up and the docs can’t be public (so GitHub with GH pages is out). We use SVN for version control.  
As an example I checked Flux’s docs and didn’t find anything that explicitly creates the versions for the releases.  
To sum up: how can I build a documentation site with versions (like Documenter.jl does)? Is it possible to do it with Documenter.jl, but without GH and GH pages?

---

<div class="post-metadata">

**Author:** ![mortenpi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mortenpi/32/158_2.png) [@mortenpi](https://discourse.julialang.org/u/mortenpi)\
**Post date:** [March 28, 2019, 9:19am UTC](https://discourse.julialang.org/t/how-documenter-makes-docs-for-different-versions/22445/2 "2019-03-28T09:19:35Z")

</div>

If you don’t have CI then you need to build it manually. Versions are normally created when the CI for a tag runs. So to get that you’d need to check out the tag, build the docs with `julia docs/make.jl` and then copy the `docs/build` directory to wherever you are storing / hosting the docs with the correct name. That’s basically it.

That is actually literally what is happening on the CI buildbot. The only other thing `deploydocs` does is that it manages the `versioninfo.js` file, which is used to make the version selector work.

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [March 28, 2019, 9:21am UTC](https://discourse.julialang.org/t/how-documenter-makes-docs-for-different-versions/22445/3 "2019-03-28T09:21:51Z")

</div>

> [@mortenpi](#):
>
> The only other thing `deploydocs` does is that it manages the `versioninfo.js` file, which is used to make the version selector work.

[`versions.js`](https://github.com/FluxML/Flux.jl/blob/gh-pages/versions.js), to be exact 🙂

In general you can just recreate the directory structure in that gh-pages branch and everything should work fine.

---

<div class="post-metadata">

**Author:** ![cserteGT3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/csertegt3/32/8283_2.png) [@cserteGT3](https://discourse.julialang.org/u/cserteGT3)\
**Post date:** [March 28, 2019, 9:39am UTC](https://discourse.julialang.org/t/how-documenter-makes-docs-for-different-versions/22445/4 "2019-03-28T09:39:41Z")

</div>

Thank you both answers! Now I understand, how can I do it with Documenter.jl.  
Is it possible to do it with only mkdocs? (Probably I should ask this at another forum on mkdocs 😃 )

---

<div class="post-metadata">

**Author:** ![mortenpi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mortenpi/32/158_2.png) [@mortenpi](https://discourse.julialang.org/u/mortenpi)\
**Post date:** [March 31, 2019, 10:26pm UTC](https://discourse.julialang.org/t/how-documenter-makes-docs-for-different-versions/22445/5 "2019-03-31T22:26:37Z")

</div>

For a manual build you would just compile with MkDocs locally and then copy the `site` directory over.

For automatic deployment you could technically re-use `deploydocs`. If you use the Markdown output in Documenter then that gets compiled by MkDocs in the end, with the entire pipeline looking like: `Markdown --(Documenter)--> Markdown --(MkDocs)--> HTML`. You end up with the MkDocs output in `site/` which `deploydocs` copies over to `gh-pages`.

---

<div class="post-metadata">

**Author:** ![cserteGT3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/csertegt3/32/8283_2.png) [@cserteGT3](https://discourse.julialang.org/u/cserteGT3)\
**Post date:** [April 3, 2019, 10:49am UTC](https://discourse.julialang.org/t/how-documenter-makes-docs-for-different-versions/22445/6 "2019-04-03T10:49:14Z")

</div>

Is the version selector gh-pages specific? (I don’t have knowledge in any website technology so this question may sounds dumb.)  
For learning/testing I cloned Flux’s gh-pages branch and I can open a specific version’s page (and check different sections/modules), but can’t change version, because that opens up the “version file”. For example if I choose v0.1, I only see `v0.1.1`  
Can I get this working locally? (I think this is the last issue that holds me back to get the whole thing to work.)

---

<div class="post-metadata">

**Author:** ![mortenpi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mortenpi/32/158_2.png) [@mortenpi](https://discourse.julialang.org/u/mortenpi)\
**Post date:** [April 4, 2019, 12:07am UTC](https://discourse.julialang.org/t/how-documenter-makes-docs-for-different-versions/22445/7 "2019-04-04T00:07:19Z")

</div>

No, it’s not specific to GitHub Pages per se. (It is Documenter-specific though.)

But the `versions.js` file it depends on is generated [here in `deploydocs`](https://github.com/JuliaDocs/Documenter.jl/blob/78e8267624253cbdd8fce1035f3c0368ba0abba9/src/Documenter.jl#L697-L702) where the versions themselves are generated by [`expand_versions` here](https://github.com/JuliaDocs/Documenter.jl/blob/78e8267624253cbdd8fce1035f3c0368ba0abba9/src/Writers/HTMLWriter.jl#L611-L691). To generate it when you are not using `deploydocs` you would have to run these yourself.

Basically, it looks at what directories (versions) you have, filters it down a bit and writes a JS file with the list of entries you should have in the version selector.

---

<div class="post-metadata">

**Author:** ![cserteGT3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/csertegt3/32/8283_2.png) [@cserteGT3](https://discourse.julialang.org/u/cserteGT3)\
**Post date:** [April 4, 2019, 7:48am UTC](https://discourse.julialang.org/t/how-documenter-makes-docs-for-different-versions/22445/8 "2019-04-04T07:48:06Z")

</div>

I understand how it is generated. My problem is, that with the cloned [Flux gh-branch](https://github.com/FluxML/Flux.jl/tree/gh-pages) I can’t select versions. I can open a specific version [v0.8.1](https://igor.xen.emi.sztaki.hu/~cstamas/Flux.jl/v0.8.1/) for example, but can’t change version, because if I click on it, it shows me the file that specifies which version to open.

The whole branch is on the server:

```bash
myuser:~/public_html/Flux.jl$ ls -loga
total 164
drwxr-xr-x 27 4096 Apr 4 09:40 .
drwxr-xr-x 3 4096 Apr 4 09:40 ..
drwxr-xr-x 12 4096 Apr 4 09:40 dev
-rwxr--r-- 1 2246 Apr 2 12:10 flux.css
drwxr-xr-x 7 4096 Apr 4 09:40 .git
-rwxr--r-- 1 7 Apr 2 12:10 .gitignore
-rwxr--r-- 1 64 Apr 2 12:10 index.html
-rwxr--r-- 1 3 Apr 2 12:10 latest
-rwxr--r-- 1 6 Apr 2 12:10 stable
-rwxr--r-- 1 6 Apr 2 12:10 v0.1
drwxr-xr-x 6 4096 Apr 4 09:40 v0.1.0
drwxr-xr-x 6 4096 Apr 4 09:40 v0.1.1
-rwxr--r-- 1 6 Apr 2 12:10 v0.2
drwxr-xr-x 6 4096 Apr 4 09:40 v0.2.0
drwxr-xr-x 6 4096 Apr 4 09:40 v0.2.1
-rwxr--r-- 1 6 Apr 2 12:10 v0.3
drwxr-xr-x 6 4096 Apr 4 09:40 v0.3.0
drwxr-xr-x 6 4096 Apr 4 09:40 v0.3.1
drwxr-xr-x 6 4096 Apr 4 09:40 v0.3.2
drwxr-xr-x 6 4096 Apr 4 09:40 v0.3.3
drwxr-xr-x 6 4096 Apr 4 09:40 v0.3.4
-rwxr--r-- 1 6 Apr 2 12:10 v0.4
drwxr-xr-x 6 4096 Apr 4 09:40 v0.4.0
drwxr-xr-x 6 4096 Apr 4 09:40 v0.4.1
-rwxr--r-- 1 6 Apr 2 12:10 v0.5
drwxr-xr-x 6 4096 Apr 4 09:40 v0.5.0
drwxr-xr-x 7 4096 Apr 4 09:40 v0.5.3
drwxr-xr-x 7 4096 Apr 4 09:40 v0.5.4
-rwxr--r-- 1 7 Apr 2 12:10 v0.6
drwxr-xr-x 7 4096 Apr 4 09:40 v0.6.10
drwxr-xr-x 7 4096 Apr 4 09:40 v0.6.7
drwxr-xr-x 7 4096 Apr 4 09:40 v0.6.8
drwxr-xr-x 7 4096 Apr 4 09:40 v0.6.9
-rwxr--r-- 1 6 Apr 2 12:10 v0.7
drwxr-xr-x 11 4096 Apr 4 09:40 v0.7.0
drwxr-xr-x 11 4096 Apr 4 09:40 v0.7.1
drwxr-xr-x 11 4096 Apr 4 09:40 v0.7.3
-rwxr--r-- 1 6 Apr 2 12:10 v0.8
drwxr-xr-x 12 4096 Apr 4 09:40 v0.8.0
drwxr-xr-x 12 4096 Apr 4 09:40 v0.8.1
-rwxr--r-- 1 137 Apr 2 12:10 versions.js

```

Could you please point me where the issue is with this setup? How should I modify the files to get the versionselector to work?

---

<div class="post-metadata">

**Author:** ![mortenpi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mortenpi/32/158_2.png) [@mortenpi](https://discourse.julialang.org/u/mortenpi)\
**Post date:** [April 4, 2019, 8:04am UTC](https://discourse.julialang.org/t/how-documenter-makes-docs-for-different-versions/22445/9 "2019-04-04T08:04:12Z")

</div>

Do you mean that you end up on a page like this?

 ![Screenshot%20from%202019-04-04%2020-58-05](https://global.discourse-cdn.com/julialang/original/3X/e/d/ed3c53e912f1450c85e94f5aa47be586eaa60c55.png)

Edit: If yes, then that is because the Flux docs are built with `HTML(prettyurls=true)` (the default), which generates `pagename/index.html` for each page. But if you open a local file with `file://`, the browser does not resolve to `index.html` files. But the version selector redirects to e.g. the `v0.8.1/` URL and not `v0.8.1/index.html`.

So for local builds you should set `HTML(prettyurls=false)` – that way it generates `pagename.html`. This way the version selectors and all internal links should work fine, even if you open it with `file://`.

Alternatively, you can also run a local webserver with e.g. `python3 -m http.server`. That way the `index.html` files get resolved and `prettyurls=true` builds work correctly too.

---

<div class="post-metadata">

**Author:** ![cserteGT3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/csertegt3/32/8283_2.png) [@cserteGT3](https://discourse.julialang.org/u/cserteGT3)\
**Post date:** [April 4, 2019, 8:14am UTC](https://discourse.julialang.org/t/how-documenter-makes-docs-for-different-versions/22445/10 "2019-04-04T08:14:21Z")

</div>

I end up on a page like this:  
 ![fluxtest](https://global.discourse-cdn.com/julialang/original/3X/d/7/d711a07da5a3a811e8793105e9af63828e9dbefb.png)

Edit: I’m aware of `prettyurl` and don’t think that it causes my problem.

---

<div class="post-metadata">

**Author:** ![mortenpi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mortenpi/32/158_2.png) [@mortenpi](https://discourse.julialang.org/u/mortenpi)\
**Post date:** [April 4, 2019, 8:19am UTC](https://discourse.julialang.org/t/how-documenter-makes-docs-for-different-versions/22445/11 "2019-04-04T08:19:52Z")

</div>

Oh, ok… that’s because of the symlinks I think. Only `vX.Y.Z` are real directories and all the `vX.Y` etc. are symlinks to the latest appropriate one. On GitHub Pages they work, but it seems that your webserver does not follow symlinks. Perhaps it’s configurable, but otherwise you may have to convert the symlinks to proper copies.

---

<div class="post-metadata">

**Author:** ![cserteGT3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/csertegt3/32/8283_2.png) [@cserteGT3](https://discourse.julialang.org/u/cserteGT3)\
**Post date:** [April 4, 2019, 8:46am UTC](https://discourse.julialang.org/t/how-documenter-makes-docs-for-different-versions/22445/12 "2019-04-04T08:46:49Z")

</div>

We configured the server so with recreating the symlinks it is working now.  
Thank you for your help!

---

<div class="post-metadata">

**Author:** ![pat-alt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pat-alt/32/34264_2.png) [@pat-alt](https://discourse.julialang.org/u/pat-alt)\
**Post date:** [April 4, 2022, 3:32pm UTC](https://discourse.julialang.org/t/how-documenter-makes-docs-for-different-versions/22445/13 "2022-04-04T15:32:01Z")

</div>

Hi there,

I’m having some trouble getting versioning to work with CI for my [package](https://www.paltmeyer.com/CounterfactualExplanations.jl/dev/). I can’t find anything obvious in the [logs](https://github.com/pat-alt/CounterfactualExplanations.jl/runs/5818782426?check_suite_focus=true#step:7:105) (see below), but my gh-pages [branch](https://github.com/pat-alt/CounterfactualExplanations.jl/tree/gh-pages) still only contains a `dev/` folder.

```julia
┌ Info: Deployment criteria for deploying devbranch build from GitHub Actions:
│ - ✔ ENV["GITHUB_REPOSITORY"]="pat-alt/CounterfactualExplanations.jl" occurs in repo="github.com/pat-alt/CounterfactualExplanations.jl.git"
│ - ✔ ENV["GITHUB_EVENT_NAME"]="push" is "push", "workflow_dispatch" or "schedule"
│ - ✔ ENV["GITHUB_REF"] matches devbranch="main"
│ - ✔ ENV["GITHUB_ACTOR"] exists and is non-empty
│ - ✔ ENV["DOCUMENTER_KEY"] exists and is non-empty
└ Deploying: ✔

```

Any idea what I’m doing wrong?

Thanks in advance.

---

<div class="post-metadata">

**Author:** ![pat-alt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pat-alt/32/34264_2.png) [@pat-alt](https://discourse.julialang.org/u/pat-alt)\
**Post date:** [April 4, 2022, 3:36pm UTC](https://discourse.julialang.org/t/how-documenter-makes-docs-for-different-versions/22445/14 "2022-04-04T15:36:33Z")

</div>

Here is my docs workflow:

```julia
docs:
    name: Documentation
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: julia-actions/setup-julia@v1
        with:
          version: '1'
      - uses: julia-actions/julia-buildpkg@v1
      - uses: julia-actions/julia-docdeploy@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }}
      - run: |
          julia --project=docs -e '
            using Documenter: DocMeta, doctest
            using CounterfactualExplanations
            DocMeta.setdocmeta!(CounterfactualExplanations, :DocTestSetup, :(using CounterfactualExplanations); recursive=true)
            doctest(CounterfactualExplanations)'
      - run: julia --project=docs docs/make.jl
        env:
          JULIA_PKG_SERVER: ""
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }}

```

I seem to remember this was all autogenerated when I originally generated the package, but perhaps something is wrong here?
