diff --git a/.github/workflows/binder.yaml b/.github/workflows/binder.yaml new file mode 100644 index 0000000..d5571b3 --- /dev/null +++ b/.github/workflows/binder.yaml @@ -0,0 +1,30 @@ +# Reference https://mybinder.readthedocs.io/en/latest/howto/gh-actions-badges.html +name: Test this PR on Binder Badge +on: + pull_request_target: + types: [opened] + +permissions: + pull-requests: + write + +jobs: + binder: + runs-on: ubuntu-latest + steps: + - name: comment on PR with Binder link + uses: actions/github-script@v3 + with: + github-token: ${{secrets.GITHUB_TOKEN}} + script: | + var PR_HEAD_USERREPO = process.env.PR_HEAD_USERREPO; + var PR_HEAD_REF = process.env.PR_HEAD_REF; + github.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/${PR_HEAD_USERREPO}/${PR_HEAD_REF}) :point_left: Test this PR on Binder` + }) + env: + PR_HEAD_REF: ${{ github.event.pull_request.head.ref }} + PR_HEAD_USERREPO: ${{ github.event.pull_request.head.repo.full_name }} diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 0000000..79153a5 --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,46 @@ +name: Build and push container image + +on: + push: + branches: + - main + +jobs: + build-and-push: + runs-on: ubuntu-latest + steps: + + # For biggish images, github actions runs out of disk space. + # So we cleanup some unwanted things in the disk image, and reclaim that space for our docker use + # https://github.com/actions/virtual-environments/issues/2606#issuecomment-772683150 + # and https://github.com/easimon/maximize-build-space/blob/b4d02c14493a9653fe7af06cc89ca5298071c66e/action.yml#L104 + # This gives us a total of about 52G of free space, which should be enough for now + - name: cleanup disk space + run: | + sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/ghc + df -h + + - name: Checkout files in repo + uses: actions/checkout@main + + - name: Build and push the image to quay.io + uses: jupyterhub/repo2docker-action@master + with: + # Make sure username & password/token pair matches your registry credentials + DOCKER_USERNAME: ${{ secrets.QUAY_USERNAME }} + DOCKER_PASSWORD: ${{ secrets.QUAY_PASSWORD }} + DOCKER_REGISTRY: "quay.io" + # Disable pushing a 'latest' tag, as this often just causes confusion + LATEST_TAG_OFF: true + # Put repo contents in /srv/repo, rather than the default (/home/jovyan). The home directory + # is mounted over by persistent storage when we are using the built image in a JupyterHub, and + # so all contents put in /home/jovyan are lost. This particularly prevents any 'start' script from + # working, as it is needed in runtime. + REPO_DIR: /srv/repo + # + # Uncomment and modify the following line with your image name, otherwise no push will happen + # IMAGE_NAME: "/" + + # Lets us monitor disks getting full as images get bigger over time + - name: Show how much disk space is left + run: df -h diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..31fb0f8 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,40 @@ +name: Test container image build + +on: + pull_request: + +jobs: + test-build: + runs-on: ubuntu-latest + steps: + + # For biggish images, github actions runs out of disk space. + # So we cleanup some unwanted things in the disk image, and reclaim that space for our docker use + # https://github.com/actions/virtual-environments/issues/2606#issuecomment-772683150 + # and https://github.com/easimon/maximize-build-space/blob/b4d02c14493a9653fe7af06cc89ca5298071c66e/action.yml#L104 + # This gives us a total of about 52G of free space, which should be enough for now + - name: cleanup disk space + run: | + sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/ghc + df -h + + - name: checkout files in repo + uses: actions/checkout@main + + - name: Build the image and push it if `NO_PUSH` disabled + uses: jupyterhub/repo2docker-action@master + with: + NO_PUSH: "true" + DOCKER_REGISTRY: "quay.io" + # Put repo contents in /srv/repo, rather than the default (/home/jovyan). The home directory + # is mounted over by persistent storage when we are using the built image in a JupyterHub, and + # so all contents put in /home/jovyan are lost. This particularly prevents any 'start' script from + # working, as it is needed in runtime. + REPO_DIR: /srv/repo + + # Uncomment and modify the following line with your image name. + # IMAGE_NAME: "/" + + # Lets us monitor disks getting full as images get bigger over time + - name: Show how much disk space is left + run: df -h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b6e4761 --- /dev/null +++ b/.gitignore @@ -0,0 +1,129 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4ac657e --- /dev/null +++ b/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2021, 2i2c-org +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..b06a237 --- /dev/null +++ b/README.md @@ -0,0 +1,56 @@ +# hub-user-image-template :paperclip: + +This is a template repository for creating dedicated user images for 2i2c hubs. + +## Overall workflow :gear: + +The overall workflow is to: + +1. Fork this repository to create your image repository + +2. Hook your image repository to quay.io + +3. Customize the image by editing repo2docker files in your image repository. + + Changes can either be done by direct commits to main on your image repository, or through a pull request from a fork of your image repository. Direct commits will build the image and push it to Quay.io. PRs will build the image and offer a link to test it using Binder. Merging the PR will cause a commit on main and therefore trigger a build and push to Quay.io. + +4. Configure your Hub to use this new image + +### In-depth guide + +Checkout the 2i2c docs for an in-depth guide on how to use this template repository to create a custom user image and use it for your hub :arrow_right: https://docs.2i2c.org/en/latest/admin/howto/environment/hub-user-image-template-guide.html. + +## About this template repository :information_source: + +This template repository enables [jupyterhub/repo2docker-action](https://github.com/jupyterhub/repo2docker-action). +This GitHub action builds a Docker image using the contents of this repo and pushes it to the [Quay.io](https://quay.io/) registry. + +### The environment + +It provides an example of a `environment.yml` conda configuration file for repo2docker to use. +This file can be used to list all the conda packages that need to be installed by `repo2docker` in your environment. +The `repo2docker-action` will update the [base repo2docker](https://github.com/jupyterhub/repo2docker/blob/HEAD/repo2docker/buildpacks/conda/environment.yml) conda environment with the packages listed in this `environment.yml` file. + +**Note:** +A complete list of possible configuration files that can be added to the repository and be used by repo2docker to build the Docker image, can be found in the [repo2docker docs](https://repo2docker.readthedocs.io/en/latest/config_files.html#configuration-files). + +### The GitHub workflows + +This template repository provides two GitHub workflows that can build and push the image to quay.io when configured. + +![Workflows](images/workflows.png) + +#### 1. Build and push container image :arrow_right: [build.yaml](https://github.com/2i2c-org/hub-user-image-template/blob/main/.github/workflows/build.yaml) + +This workflow is triggered by every pushed commit on the main branch of the repo (including when a PR is merged). +It **builds** the image and **pushes** it to the registry. + +#### 2. Test container image build :arrow_right: [test.yaml](https://github.com/2i2c-org/hub-user-image-template/blob/MAIN/.github/workflows/test.yaml) + +This workflow is triggerd by every Pull Request commit and it **builds** the image, but it **doesn't** push it to the registry, unless explicitly configured to do so. Checkout [this section](https://docs.2i2c.org/en/latest/admin/howto/environment/hub-user-image-template-guide.html#enable-quay-io-image-push-for-test-yaml) on how to enable image pushes on Pull Requests. + +#### 3. Test this PR on Binder Badge :arrow_right: [binder.yaml](https://github.com/2i2c-org/hub-user-image-template/blob/MAIN/.github/workflows/binder.yaml) + +This workflow posts a comment inside a pull request, every time a pull request gets opened. The comment contains a "Test this PR on Binder" badge, which can be used to access the image defined by the PR in [mybinder.org](https://mybinder.org/). + +![Test this PR on Binder](images/binder-badge.png) diff --git a/environment.yml b/environment.yml new file mode 100644 index 0000000..10d9a47 --- /dev/null +++ b/environment.yml @@ -0,0 +1,16 @@ +# This is the standard conda configuration file. Use this file to list +# the conda packages that you need installed in your environment. +channels: + - conda-forge + +dependencies: + - jupyter_contrib_nbextensions==0.5.1 + # Required until https://github.com/jupyterhub/repo2docker/pull/1196 is merged + - jupyterhub-singleuser>=3.0,<4.0 + # Set default python version to 3.10 - repo2docker sets it to 3.7 instead by default, + # which can limit us to older package versions + - python=3.10 + # Everyone wants to use nbgitpuller for everything, so let's do that + - nbgitpuller=1.1.* + # Add other packages here + # - diff --git a/images/binder-badge.png b/images/binder-badge.png new file mode 100644 index 0000000..9326987 Binary files /dev/null and b/images/binder-badge.png differ diff --git a/images/workflows.png b/images/workflows.png new file mode 100644 index 0000000..0c7dce5 Binary files /dev/null and b/images/workflows.png differ