PandocMissing when building Sphinx documentation - github

I am working on using GitHub Actions to build and deploy some Sphinx documentation to GitHub pages and am running into a problem. When the action runs, I get the error:
Notebook error:
183
PandocMissing in examples/Admissions Data.ipynb:
184
Pandoc wasn't found.
185
Please check that pandoc is installed:
186
https://pandoc.org/installing.html
187
make: *** [Makefile:20: html] Error 2
This is very similar to this question Building docs fails due to missing pandoc, but when I try out the solutions outlined in these answers it does not fix the problem. Also, I am using Sphinx not read the docs.
My sphinx.yml file (according to the suggestion outlined in the deploying Sphinx docs online tutorial) is:
name: Sphinx build
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v3
- name: Build HTML
uses: ammaraskar/sphinx-action#master
- name: Upload artifacts
uses: actions/upload-artifact#v3
with:
name: html-docs
path: docs/build/html/
- name: Deploy
uses: peaceiris/actions-gh-pages#v3
if: github.ref == 'refs/heads/main'
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: docs/build/html
Additionally, my requirements.txt file is:
furo==2021.11.16
nbsphinx
sphinx_gallery
sphinx_rtd_theme
markupsafe==2.0.1
geostates
geopandas
pandas
jinja2>=3.0
pypandoc
Clearly something is breaking here with the pandoc installation where I have .ipynb files tying to be converted into markdown files to be rendered in HTML. Does anyone have an insight into what the fix is here? I tried adding the code from the answer in the aforementioned question into my conf.py file but this did not fix the problem. I am thinking it might have to do with conda vs pip, but I am not sure how to fix this.
My repo for this testing project is available here where you can view the entire build error messages under the Actions tab.
Update: It seems like I need to do (possible) something related to adding some lines of code in the sphinx.yml file?
EDIT 9/1/22:
From reading the Pandoc tutorial online is says that something along the lines of:
name: Simple Usage
on: push
jobs:
convert_via_pandoc:
runs-on: ubuntu-18.04
steps:
- uses: docker://pandoc/core:2.9
with:
args: "--help" # gets appended to pandoc command
is how Pandoc is set up with GitHub Actions. The only thing is I am pretty confused about how to integrate this code into the sphinx.yml file (where and what code to copy over) and which commands to pass through as the arguments?

The error happens in the ammaraskar/sphinx-action#master action. The action sets up it's own Docker container, so installing pandoc in the main runner will have no effect.
The docs of that action make it seem like it should be possible to install pandoc by setting an appropriate pre-build-command, e.g.,
- name: Build HTML
uses: ammaraskar/sphinx-action#master
with:
pre-build-command: >-
apt-get update && apt-get install -y pandoc
However, this does not work; there is a pull requests that might fix this, but it hasn't been merged.
One possibility, that has also been noted in the comments by #mzjn, would be to use pypandoc_binary instead of pypandoc in file docs/requirements.txt. This would usually be the preferred solution. However, the versions used in the action image are rather old, so the installer cannot find a matching version, and the installer errors with a message that it "cannot find a matching distribution for pypandoc_binary".
It therefore seems like the only real option is to use a different action, or to fork and fix ammaraskar/sphinx-action. E.g., after forking the repository on GitHub, the action's Dockerfile can be changed to include a copy of pandoc:
COPY --from=pandoc/minimal:2.19.2 /pandoc /usr/bin/pandoc
Adding the above line somewhere in the middle of the Dockerfile will include a statically compiled pandoc binary in the imaged used to run the action.
The new action can be used by replacing ammaraskar/sphinx-action in sphinx.yml with the name of the new fork. Everything should run smoothly with that in place.

Related

Setup Github action to download a zip file

I have a Google Chrome and Mozilla Firefox extension in a same GitHub repository. They are separated in two branches and I am "exposing" the original URL to download the repository for each branch:
The approach to install a Firefox extension is quite long and messy since it needs to be unzipped and zipped again. So, someone recommended me using Github actions to create a release file from specific branches using this Github action: Zip Release.
According to their documentation I have tried to replicate the YAML file for my use case using the Github action creation wizard and naming that file firefox.yml that created a folder in the repository root: .github/workflows/firefox.yml:
name: Create Archive
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: my-user/the-repo#dev-firefox
- name: Create Firefox Release
uses: thedoctor0/zip-release#main
with:
type: 'zip'
filename: 'dev-firefox.zip'
path: './releases'
exclusions: '*.git* /*node_modules/* .editorconfig /*releases/*'
But after it starts it immediately fails with the following message:
Can't find 'action.yml', 'action.yaml' or 'Dockerfile' under '/home/runner/work/_actions/my-user/the-repo/dev-firefox'. Did you forget to run actions/checkout before running your local action?
I also tried adding - uses: actions/checkout#master just before the line - uses my-user/the-repo#dev-firefox but it won't work.
Not sure how to properly write the workflow YAML configuration. Any suggestions?
You're confusing uses with checking out a repository. uses indicates an action to use, with the part after the # specifying the version of the action. To check out a specific branch of your repo, you can use the checkout action with the ref parameter:
steps:
- uses: actions/checkout#v3.1.0
with:
ref: dev-firefox

How to set up actions in GitHub for new user?

I just got a GitHub account and writing small scripts in Python which I am learning.
While adding my code to GitHub I noticed there is an option to run tests/validation on my code but mine is empty.
I googled around and found that lint and black and are good checks.
I found this Action that I want to add - https://github.com/marketplace/actions/python-quality-and-format-checker
There is a "script" and a "config" that I think I need to add/update somewhere. Also when I click "Use latest version" it tells me to add the code into some .yml.
Can anyone assist me in installing this Action or point me in the right direction? Also, how can I use this Action on all my repositories/code?
=======================================
EDIT:
This link has the instructions - https://help.github.com/en/actions/configuring-and-managing-workflows/configuring-a-workflow
place yaml or yml in this directory -> .github/workflows
For this Action: https://github.com/marketplace/actions/python-quality-and-format-checker
the code inside the file will look like this:
on: [push, pull_request]
name: Python Linting
jobs:
PythonLinting:
name: Python linting
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#master
- name: Konstruktoid Python linting
uses: konstruktoid/action-pylint#master
thanks to: bertrand martel
pylint is part of the new GitHub Super Linter (github/super-linter):
Introducing GitHub Super Linter: one linter to rule them all
The Super Linter is a source code repository that is packaged into a Docker container and called by GitHub Actions. This allows for any repository on GitHub.com to call the Super Linter and start utilizing its benefits.
When you’ve set your repository to start running this action, any time you open a pull request, it will start linting the code case and return via the Status API.
It will let you know if any of your code changes passed successfully, or if any errors were detected, where they are, and what they are.
This then allows the developer to go back to their branch, fix any issues, and create a new push to the open pull request.
At that point, the Super Linter will run again and validate the updated code and repeat the process.
And you can set it up to only int new files if you want.
Update August 2020:
github/super-linter issue 226 has been closed with PR 593:
This Pr will add:
Black python linting
Updated tests

How to install an old version of the Direct X Api in GitHub actions

I'm working on an implementation of continuous integration in this project, which requires an old version of the DirectX SDK from June 2010. Is it possible to install this as a part of a GitHub Actions workflow at all? It may build with any version of the SDK as long as it's compatible with Windows 7.
Here's the workflow I've written so far, and here's the general building for Windows guide I'm following...
I have a working setup for project using DX2010, however i am not running installer (which always failed for me during beta, maybe it's fixed nowadays) but extracting only parts required for build. Looking at link you provided, this is exactly what guide recommends :)
First, DXSDK_DIR variable is set using ::set-env "command". Variable most likely should point to directory outside default location, which can be overwritten if repository is checked out after preparing DX files.
- name: Config
run: echo ::set-env name=DXSDK_DIR::$HOME/cache/
shell: bash
I didn't want to include DX files in repository, so they had to be downloaded when workflow is running. To avoid doing that over and over again cache action is used to keep files between builds.
- name: Cache
id: cache
uses: actions/cache#v1
with:
path: ~/cache
key: cache
And finally, downloading and extracting DX2010. This step will run only if cache wasn't created previously or current workflow cannot create/restore caches (like on: schedule or on: repository_dispatch).
- name: Cache create
if: steps.cache.outputs.cache-hit != 'true'
run: |
curl -L https://download.microsoft.com/download/a/e/7/ae743f1f-632b-4809-87a9-aa1bb3458e31/DXSDK_Jun10.exe -o _DX2010_.exe
7z x _DX2010_.exe DXSDK/Include -o_DX2010_
7z x _DX2010_.exe DXSDK/Lib/x86 -o_DX2010_
mv _DX2010_/DXSDK $HOME/cache
rm -fR _DX*_ _DX*_.exe
shell: bash
Aaand that's it, project is ready for compilation.

How do I cache steps in GitHub actions?

Say I have a GitHub actions workflow with 2 steps.
Download and compile my application's dependencies.
Compile and test my application
My dependencies rarely change and the compiled dependencies can be safely cached until I next change the lock-file that specifies their versions.
Is a way to save the result of the first step so that in future workflow can skip over that step?
Most use-cases are covered by existing actions, for example:
actions/setup-node for JS
docker/build-push-action for Docker
Custom caching is supported via the cache action. It works across both jobs and workflows within a repository. See also: GitHub docs and Examples.
Consider the following example:
name: GitHub Actions Workflow with NPM cache
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v3
- name: Cache NPM dependencies
uses: actions/cache#v3
with:
path: ~/.npm
key: ${{ runner.OS }}-npm-cache-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.OS }}-npm-cache-
- name: Install NPM dependencies
run: npm install
How caching works step-by-step:
At the Cache NPM dependencies step, the action will check if there's an existing cache for the current key
If no cache is found, it will check spatial matches using restore-keys. In this case, if package-lock.json changes, it will fall back to a previous cache. It is useful to prefix keys and restore keys with the OS and name of the cache, as it shouldn't load files for a different type of cache or OS.
If any cache is found, it will load the files to path
The CI continues to the next step and can use the filed loaded from the cache. In this case, npm install will use the files in ~/.npm to save downloading them over the network (note that for NPM, caching node_modules directly is not recommended).
At the end of the CI run a post-action is executed to save the updated cache in case the key changes. This is not explicitly defined in the workflow, rather it is built into the cache action to take care of both loading and saving the cache.
You can also build your own reusable caching logic with #actions/cache such as:
1-liner NPM cache
1-liner Yarn cache
Old answer:
Native caching is not currently possible, expected to be implemented by mid-November 2019.
You can use artifacts (1, 2) to move directories between jobs (within 1 workflow) as proposed on the GH Community board. This, however, doesn't work across workflows.
The cache action can only cache the contents of a folder. So if there is such a folder, you may win some time by caching it.
For instance, if you use some imaginary package-installer (like Python's pip or virtualenv, or NodeJS' npm, or anything else that puts its files into a folder), you can win some time by doing it like this:
- uses: actions/cache#v2
id: cache-packages # give it a name for checking the cache hit-or-not
with:
path: ./packages/ # what we cache: the folder
key: ${{ runner.os }}-packages-${{ hashFiles('**/packages*.txt') }}
restore-keys: |
${{ runner.os }}-packages-
- run: package-installer packages.txt
if: steps.cache-packages.outputs.cache-hit != 'true'
So what's important here:
We give this step a name, cache-packages
Later, we use this name for conditional execution: if, steps.cache-packages.outputs.cache-hit != 'true'
Give the cache action a path to the folder you want to cache: ./packages/
Cache key: something that depends on the hash of your input files. That is, if any packages.txt file changes, the cache will be rebuilt.
The second step, package installer, will only be run if there was no cache
For users of virtualenv: if you need to activate some shell environment, you have to do it in every step. Like this:
- run: . ./environment/activate && command
My dependencies rarely change and the compiled dependencies can be safely cached until I next change the lock-file that specifies their versions. Is a way to save the result of the first step so that in future workflow can skip over that step?
The first step being:
Download and compile my application's dependencies.
GitHub Actions themselves will not do this for you. The only advice I can give you is that you adhere to Docker best practices in order to ensure that if Actions do make use of docker caching, your image could be re-used instead of rebuilt. See: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache
When building an image, Docker steps through the instructions in your Dockerfile, executing each in the order specified. As each instruction is examined, Docker looks for an existing image in its cache that it can reuse, rather than creating a new (duplicate) image.
This also implies that the underlying system of GitHub Actions can/will leverage the Docker caching.
However things like compilation, Docker won't be able to use the cache mechanism, so I suggest you think very well if this is something you desperately need. The alternative is to download the compiled/processed files from an artifact store (Nexus, NPM, MavenCentral) to skip that step. You do have to weight the benefits vs the complexity you are adding to your build on this.
This is now natively supported using: https://help.github.com/en/actions/automating-your-workflow-with-github-actions/caching-dependencies-to-speed-up-workflows.
This is achieved by using the new cache action: https://github.com/actions/cache
If you are using Docker in your WorkFlows, as #peterevans answered, GitHub now supports caching through the cache action, but it has its limitations.
For that reason, you might find useful this action to bypass GitHub's action limitations.
Disclaimer: I created the action to support cache before GitHub did it officially, and I still use it because of its simplicity and flexibility.
I'll summarize the two options:
Caching
Docker
Caching
You can add a command in your workflow to cache directories. When that step is reached, it'll check if the directory that you specified was previously saved. If so, it'll grab it. If not, it won't. Then in further steps you write checks to see if the cached data is present. For example, say you are compiling some dependency that is large and doesn't change much. You could add a cache step at the beginning of your workflow, then a step to build the contents of the directory if they aren't there. The first time that you run it won't find the files but subsequently it will and your workflow will run faster.
Behind the scenes, GitHub is uploading a zip of your directory to github's own AWS storage. They purge anything older than a week or if you hit a 2GB limit.
Some drawbacks with this technique is that it saves just directories. So if you installed into /usr/bin, you'll have to cache that! That would be awkward. You should instead install into $home/.local and use echo set-env to add that to your path.
Docker
Docker is a little more complex and it means that you have to have a dockerhub account and manage two things now. But it's way more powerful. Instead of saving just a directory, you'll save an entire computer! What you'll do is make a Dockerfile that will have in it all your dependencies, like apt-get and python pip lines or even long compilation. Then you'll build that docker image and publish it on dockerhub. Finally, you'll have your tests set to run on that new docker image, instead of on eg, ubuntu-latest. And from now on, instead of installing dependencies, it'll just download the image.
You can automate this further by storing that Dockerfile in the same GitHub repo as the project and then write a job with steps that will download the latest docker image, rebuild if necessary just the changed steps, and then upload to dockerhub. And then a job which "needs" that one and uses the image. That way your workflow will both update the docker image if needed and also use it.
The downsides is that your deps will be in one file, the Dockerfile, and the tests in the workflow, so it's not all together. Also, if the time to download the image is more than the time to build the dependencies, this is a poor choice.
I think that each one has upsides and downsides. Caching is only good for really simple stuff, like compiling into .local. If you need something more extensive, Docker is the most powerful.

Rustdoc on gh-pages with Travis

I have generated documentation for my project with cargo doc, and it is made in the target/doc directory. I want to allow users to view this documentation without a local copy, but I cannot figure out how to push this documentation to the gh-pages branch of the repository. Travis CI would help me automatically do this, but I cannot get it to work either. I followed this guide, and set up a .travis.yml file and a deploy.sh script. According to the build logs, everything goes fine but the gh-pages branch never gets updated. My operating system is Windows 7.
It is better to use travis-cargo, which is intended to simplify deploying docs and which also has other features. Its readme provides an example of .travis.yml file, although in the simplest form it could look like this:
language: rust
sudo: false
rust:
- nightly
- beta
- stable
before_script:
- pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
script:
- |
travis-cargo build &&
travis-cargo test &&
travis-cargo --only beta doc
after_success:
- travis-cargo --only beta doc-upload
# needed to forbid travis-cargo to pass `--feature nightly` when building with nightly compiler
env:
global:
- TRAVIS_CARGO_NIGHTLY_FEATURE=""
It is very self-descriptive, so it is obvious, for example, what to do if you want to use another Rust release train for building docs.
In order for the above .travis.yml to work, you need to set your GH_TOKEN somehow. There are basically two ways to do it: inside .travis.yml via an encrypted string, or by configuring it in the Travis itself, in project options. I prefer the latter way, so I don't need to install travis command line tool or pollute my .travis.yml (and so the above config file does not contain secure option), but you may choose otherwise.