# Link Checking with GitHub Actions not Working

**URL:** <https://discourse.julialang.org/t/link-checking-with-github-actions-not-working/61823>\
**Category:** Tooling\
**Tags:** documenter\
**Created:** [May 25, 2021, 11:02pm UTC](https://discourse.julialang.org/t/link-checking-with-github-actions-not-working/61823 "2021-05-25T23:02:27Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![pulsipher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pulsipher/32/10461_2.png) [@pulsipher](https://discourse.julialang.org/u/pulsipher)\
**Post date:** [May 25, 2021, 11:02pm UTC](https://discourse.julialang.org/t/link-checking-with-github-actions-not-working/61823/1 "2021-05-25T23:02:27Z")

</div>

When I build my docs locally, they run the link checks without issue with `linkcheck = true`. However, when I build the docs via GitHub Actions on `ubuntu-latest` I get `Warning: linkcheck requires curl`. which indicates it cannot find an installation `curl`. To ensure that `curl` is installed, I added a curl installation step before building the docs which shows that `curl` is indeed installed, but still is not being recognized by Documenter.

I am stumped on how to resolve this. Here is a link to my latest run: [Overhaul of Variables and Constraints (#135) · infiniteopt/InfiniteOpt.jl@f0e9d23 · GitHub](https://github.com/pulsipher/InfiniteOpt.jl/runs/2670047661?check_suite_focus=true)

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [May 26, 2021, 8:50am UTC](https://discourse.julialang.org/t/link-checking-with-github-actions-not-working/61823/2 "2021-05-26T08:50:51Z")

</div>

That is strange. Documenter checks if `success(`curl --version`)`, can you print the result of that? And maybe also the result of `Sys.which("curl")`.

---

<div class="post-metadata">

**Author:** ![pulsipher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pulsipher/32/10461_2.png) [@pulsipher](https://discourse.julialang.org/u/pulsipher)\
**Post date:** [May 26, 2021, 2:10pm UTC](https://discourse.julialang.org/t/link-checking-with-github-actions-not-working/61823/3 "2021-05-26T14:10:47Z")

</div>

I added the following shell command to my workflow in the “Check curl” section:

```julia
> julia -e 'println(success(`curl --version`)); println(Sys.which("curl"))'

```

Which yields:

```julia
true
/usr/bin/curl

```

However, with the documentation build I still get:

```julia
> julia --project=docs/ --color=yes docs/make.jl
[ Info: SetupBuildDirectory: setting up build directory.
[ Info: Doctest: running doctests.

******************************************************************************
This program contains Ipopt, a library for large-scale nonlinear optimization.
 Ipopt is released as open source code under the Eclipse Public License (EPL).
         For more information visit http://projects.coin-or.org/Ipopt
******************************************************************************

[ Info: ExpandTemplates: expanding markdown templates.
[ Info: CrossReferences: building cross-references.
[ Info: CheckDocument: running document checks.
┌ Warning: linkcheck requires `curl`.
└ @ Documenter.DocChecks ~/.julia/packages/Documenter/bFHi4/src/DocChecks.jl:185
[ Info: Populate: populating indices.
[ Info: RenderDocument: rendering document.
[ Info: HTMLWriter: rendering HTML pages.
┌ Info: Deployment criteria for deploying preview build from GitHub Actions:
│ - ✔ ENV["GITHUB_REPOSITORY"]="pulsipher/InfiniteOpt.jl" occurs in repo="github.com/pulsipher/InfiniteOpt.jl"
│ - ✔ ENV["GITHUB_REF"] corresponds to a PR number
│ - ✔ `push_preview` keyword argument to deploydocs is `true`
│ - ✔ ENV["GITHUB_ACTOR"] exists and is non-empty
│ - ✔ ENV["DOCUMENTER_KEY"] exists and is non-empty
└ Deploying: ✔
.
.
.

```

Here is the link to this latest run: [WIP Link Test Debugging · infiniteopt/InfiniteOpt.jl@253d9ae · GitHub](https://github.com/pulsipher/InfiniteOpt.jl/runs/2675791962?check_suite_focus=true)

---

<div class="post-metadata">

**Author:** ![pulsipher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pulsipher/32/10461_2.png) [@pulsipher](https://discourse.julialang.org/u/pulsipher)\
**Post date:** [June 10, 2021, 6:48pm UTC](https://discourse.julialang.org/t/link-checking-with-github-actions-not-working/61823/4 "2021-06-10T18:48:44Z")

</div>

Ok when I switch to Julia 1.6 I got this more helpful error message:

```julia
curl: /opt/hostedtoolcache/julia/1.6.1/x64/bin/../lib/julia/libcurl.so.4: no version information available (required by curl)

```

Which relates to [this stack exchange](https://stackoverflow.com/questions/30017397/error-curl-usr-local-lib-libcurl-so-4-no-version-information-available-requ). When I run `locate libcurl.so.4` on GitHub Actions using ubuntu-latest (after installing the documentation julia dependencies) I get:

```julia
/opt/hostedtoolcache/julia/1.6.1/x64/lib/julia/libcurl.so.4
/opt/hostedtoolcache/julia/1.6.1/x64/lib/julia/libcurl.so.4.7.0
/usr/lib/x86_64-linux-gnu/libcurl.so.4
/usr/lib/x86_64-linux-gnu/libcurl.so.4.6.0
/usr/local/julia1.6.1/lib/julia/libcurl.so.4
/usr/local/julia1.6.1/lib/julia/libcurl.so.4.7.0

```

Hence, Julia installed a version of libcurl that is different that the one already installed. Thus a workflow like this should fix the problem:

```julia
name: Documentation
on:
  push:
    branches: [master]
    tags: '*'
  pull_request:
    types: [opened, synchronize, reopened]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: julia-actions/setup-julia@latest
        with:
          version: '1.6' # Build documentation on Julia 1.6
      - name: Install julia dependencies
        run: julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
      - name: Fix curl mismatch # (https://stackoverflow.com/questions/30017397/error-curl-usr-local-lib-libcurl-so-4-no-version-information-available-requ)
        run: |
             julia_libcurl="$(dirname "$(which julia)")/../lib/julia/libcurl.so.4"
             sudo rm $julia_libcurl
             sudo ln -s /usr/lib/x86_64-linux-gnu/libcurl.so.4 $julia_libcurl
      - name: Build and deploy
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # For authentication with GitHub Actions token
          DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} # For authentication with SSH deploy key
        run: julia --project=docs/ --color=yes docs/make.jl

```

When I run the above, I am able to linkcheck without issue.

To limit the amount of hardcoding needed, we can instead run:

```julia
sys_libcurl="$(find /usr/lib/x86_64-linux-gnu -maxdepth 1 -name "libcurl.so.*" | sort -n | tail -1)"
julia_lib="$(dirname "$(which julia)")/../lib/julia"
julia_libcurl="$(find $julia_lib -maxdepth 1 -name "libcurl.so.[0-9]" | sort -n | tail -1)"
sudo rm $julia_libcurl
sudo ln -s $sys_libcurl $julia_libcurl

```

This will search for the right `libcurl.so.x` versions instead of hard coding `libcurl.so.4`.

Someone with a better knowledge of the innerworkings could probably come up with a less hacky solution, but this is the best I could come up with.

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [June 10, 2021, 9:15pm UTC](https://discourse.julialang.org/t/link-checking-with-github-actions-not-working/61823/5 "2021-06-10T21:15:51Z")

</div>

Is someone or something setting `LD_LIBRARY_PATH`? That can interfere with things like this.

---

<div class="post-metadata">

**Author:** ![pulsipher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pulsipher/32/10461_2.png) [@pulsipher](https://discourse.julialang.org/u/pulsipher)\
**Post date:** [June 10, 2021, 9:39pm UTC](https://discourse.julialang.org/t/link-checking-with-github-actions-not-working/61823/6 "2021-06-10T21:39:44Z")

</div>

I checked at various points in the build and it appears that `LD_LIBRARY_PATH` is never set by anything. It appears the extra `libcurl` is introduced when `julia-actions/setup-julia@latest` is included and that causes the `curl: /opt/hostedtoolcache/julia/1.6.1/x64/bin/../lib/julia/libcurl.so.4: no version information available (required by curl)` problem when documenter uses `curl` to linkcheck. I have only been able to remedy the problem with the hacky bash script shown above.

---

<div class="post-metadata">

**Author:** ![pulsipher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pulsipher/32/10461_2.png) [@pulsipher](https://discourse.julialang.org/u/pulsipher)\
**Post date:** [June 12, 2021, 3:07pm UTC](https://discourse.julialang.org/t/link-checking-with-github-actions-not-working/61823/7 "2021-06-12T15:07:26Z")

</div>

@fredrikekre You were exactly right. I tried to figure out a minimum working example ([GitHub - pulsipher/JuliaCurlTest](https://github.com/pulsipher/JuliaCurlTest)) and figured out the problem lies with `Ipopt.jl`. I can replicate the error using the following script (let’s call it `curl.jl`):

```julia
import Pkg; Pkg.add("Ipopt"); import Ipopt
run(`curl -sI https://google.com/`)

```

when it is run in the workflow:

```nohighlight
name: Curl Test
on:
  workflow_dispatch:
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: julia-actions/setup-julia@latest
        with:
          version: '1.6'
      - run: julia curl.jl

```

We get the error:

```julia
curl: /opt/hostedtoolcache/julia/1.6.1/x64/bin/../lib/julia/libcurl.so.4: no version information available (required by curl)

```

It appears this occurs because `Ipopt.jl` sets `LD_LIBRARY_PATH`:

> <https://github.com/jump-dev/Ipopt.jl/blob/5cbb08da95ddae85cb501e648aac20da97a32be1/src/Ipopt.jl#L98-L106>

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [June 12, 2021, 4:06pm UTC](https://discourse.julialang.org/t/link-checking-with-github-actions-not-working/61823/8 "2021-06-12T16:06:07Z")

</div>

Interesting. Would be nice if Ipopt didn’t do that, but perhaps it is necessary for some reason. In any case it might be possible to guard against this in Documenter perhaps.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [June 12, 2021, 5:45pm UTC](https://discourse.julialang.org/t/link-checking-with-github-actions-not-working/61823/9 "2021-06-12T17:45:44Z")

</div>

Maybe using LibCurl.jl stdlib instead of manually calling `curl` would work?

---

<div class="post-metadata">

**Author:** ![pulsipher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pulsipher/32/10461_2.png) [@pulsipher](https://discourse.julialang.org/u/pulsipher)\
**Post date:** [June 21, 2021, 4:02pm UTC](https://discourse.julialang.org/t/link-checking-with-github-actions-not-working/61823/10 "2021-06-21T16:02:49Z")

</div>

As an update, Ipopt.jl `v0.7.0` was released which removes its use of `LD_LIBRARY_PATH` and thus resolves the problem.
