jupyterhub / zero-to-jupyterhub-k8s

Helm Chart & Documentation for deploying JupyterHub on Kubernetes
https://zero-to-jupyterhub.readthedocs.io
Other
1.56k stars 799 forks source link

CircleCI vs readthedocs - what is building our docs? #1176

Closed consideRatio closed 5 years ago

consideRatio commented 5 years ago

We have a .circleci folder and a readthedocs.yml file, both seem related to building documentation.

Do they both serve a purpose or is one not in use? I understand it as we are only using readthedocs right now.

/cc: @willingc @choldgraf

choldgraf commented 5 years ago

yep, the readthedocs.yml file is what serves our actual public-facing documentation, and the circleci build lets us preview the documentation inside the PR before it's actually deployed live!

consideRatio commented 5 years ago

Aha that explains it :D Excellent I setup a full readthedocs solution for my fork in order to do this as I lacked understanding about this hahaha!

consideRatio commented 5 years ago

@choldgraf how do I inspect the docs of a PR?

willingc commented 5 years ago

@consideRatio I typically pull the PR and build locally (or push to a branch on my test repo on RTD).

choldgraf commented 5 years ago

@consideRatio from the PR, you can click on the CircleCI build (called "build docs"):

image

Then click Artifacts, then you'll see a list of the built documentation. Click index.html to be taken to the documentation built off of that PR. For example, here's the documentation build from your #1175 PR

https://252-87849371-gh.circle-artifacts.com/0/html/index.html

choldgraf commented 5 years ago

(if that's not clear and we should add it in the contributors guide somewhere, I'd be happy to iterate on it w/ somebody!)

consideRatio commented 5 years ago

@choldgraf ah I needed to be logged in and part of the JupyterHub team as well to see it it seems. Thanks for the help. Perhaps it is configurable to make this projects CircleCI artifacts public?

consideRatio commented 5 years ago

Hmm... Perhaps the artifacts tab is visible if one is logged in to circleci even though one isn't part of the JH team.

Confirmed the artifacts on https://circleci.com/gh/deathcap/GlowstonePlusPlus are downloadable after logging in as a new user via GitHub, so I think CircleCI should be sufficient for hosting these builds for now, since anyone who wants to report issues already has to have a GitHub account.

Also, perhaps we can also directlink an artifact even though the tab isn't visible: https://github.com/GlowstoneMC/Glowstone/issues/3#issuecomment-189753866

choldgraf commented 5 years ago

The CircleCI build stuff we actually snagged from scikit-learn, which has some custom javascript that will add a button to the PR to let you view the documentation. The JS figures out what's the URL of the built documentation. I'd love something like this! Just haven't had the hours in the day :-(

betatim commented 5 years ago

Do you have a link to the JS that scikit-learn uses?

I made https://github.com/betatim/notebook-bot which will go through the artifacts of a PR and post a link in the PR thread. We could base a "post link to rendered docs" bot on that. The bot itself is hosted on glitch.com which seems to work very well.

choldgraf commented 5 years ago

OK, I spent an hour digging, found @lesteve 's script he originally shared w/ us a few months ago (thanks @lesteve !) and updated it so that it works with z2jh docs. Here's some greasemonkey javascript that works for me:

NOTE: This script is to be used with a browser extension

// ==UserScript==
// @name        see PR doc on CircleCI
// @namespace   github.com
// @include     /https://github.com/.*/pull/[0-9]+[^/]*$/
// @grant       none
// ==/UserScript==

// Add a button to easily access HTML generated documentation on CircleCI
(function(){
    'use strict';

    // This is a unique number for each CircleCI project
    const CIRCLECI_NUM = "87849371";
    const BUTTON_TEXT = "Preview Built Docs";

    // Add buttons upon startup
    window.addEventListener('load', () => {
        var link = getCircleArtifactLink();
        addButton(BUTTON_TEXT, link);
    });

    function addButton(text, link, cssObj) {
        // Create a link to the built docs
        let buttonLink = document.createElement('a');
        buttonLink.href = link;

        // Add the button underneath the link
        let headerActionElement = document.getElementsByClassName('gh-header-actions')[0];
        cssObj = cssObj || {};
        let button = document.createElement('button'), btnStyle = button.style;
        button.innerHTML = text;
        button.classList = "btn btn-sm";
        button.type = "button";
        Object.keys(cssObj).forEach(key => btnStyle[key] = cssObj[key]);

        // Append the button to the link, and the link to the header
        buttonLink.appendChild(button)
        headerActionElement.appendChild(buttonLink);
        return button;
    }

    function getCircleArtifactLink() {
        var circleElement;
        var useCircleWorkflow;
        const jobSelectorText = "div.merge-status-item a.status-actions"

        if (circleElement !== undefined) {
            return;
        }

        // Find all elements for build jobs
        var elements = document.querySelectorAll(jobSelectorText);

        // Return elements that have circleci in the text
        // querySelector will return a NodeList so this treats it as an array
        var circleElements = Array.prototype.filter.call(elements, function(element){
            return (element.href.indexOf("circleci.com") !== -1);
        });
        // circleElements should be a list of length 1 so we'll just take the first element
        circleElement = circleElements[0]

        // Split up the circleElement's href into parts so we can grab the build number (will be last element in linkParts)
        var linkParts = circleElement.href.split('?')[0].split('/')
        var circleBuildNumber = linkParts[linkParts.length - 1];
        var docURLPart = '-'+CIRCLECI_NUM+'-gh.circle-artifacts.com/0/html';
        var docURL = 'https://' + circleBuildNumber + docURLPart + '/index.html';

        return docURL;
    }
}());

This results in this little button that takes you to the docs:

image

The only thing that is hard-coded in there is the number of the project (coded above as CIRCLECI_NUM). I believe that's unique to each project.

consideRatio commented 5 years ago

Wohooo cool, finally got to use a greasemonkey / user script. I have not done that before, only heard about them. Thanks @choldgraf !

choldgraf commented 5 years ago

@consideRatio did it work?!

I suppose one edit we could make is to check the URL for the github org/repo, and then have a dictionary of project numbers so that the same script would work on multiple repositories

consideRatio commented 5 years ago

it worked chris! :D

choldgraf commented 5 years ago

where is a good place to put that greasemonkey/tampermonkey script so that others on the team could discover it?

or maybe @betatim has thoughts on how we could semi-automate this with a bot?

betatim commented 5 years ago

For bot based automating: https://github.com/jupyterhub/zero-to-jupyterhub-k8s/issues/1176#issuecomment-469157619 🤖

choldgraf commented 5 years ago

I don't know much about how to use bots like that...perhaps there is less immediate complexity in just pasting that XXXmonkey script in the team-compass so that others can discover/use that code?

willingc commented 5 years ago

Let's chat as well about services like now that offer a link to rendered docs at next week's team meeting.

lesteve commented 5 years ago

Glad to see my modest JavaScript skills are useful for other projects!

choldgraf commented 5 years ago

@lesteve be careful about signaling any degree of modest javascript skills, you may find yourself asked to contribute to jupyter one day ;-)