Add LICENSE, README and some config #15
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Build | |
on: | |
pull_request: | |
paths-ignore: | |
- "docs/**" | |
push: | |
paths-ignore: | |
- "docs/**" | |
branches-ignore: | |
- "dependabot/**" | |
- "pre-commit-ci-update-config" | |
workflow_dispatch: | |
# Tags are calculated based on the existing tags in the repository | |
# so we can only run builds consecutively, otherwise two images in | |
# different builds may have the same tag. | |
# If there are multiple pending jobs older pending jobs will be cancelled. | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref }} | |
env: | |
# If we're on this branch don't bother fetching every tag since we know | |
# this will be the most recent tag, i.e. builds on this branch should always | |
# update the `latest` tag | |
LATEST_BRANCH: main | |
# Only push images if this workflow is run on this branch | |
# This ensures if a a new branch is created in this repo it won't automatically | |
# push an image. | |
# If this is a backport then change this to the name of the backports branch | |
PUBLISH_BRANCH: main | |
# IMAGE: jupyterhub/jupyterhub | |
IMAGE: manics/jupyterhub-image-test | |
SINGLEUSER: manics/jupyterhub-singleuser-image-test | |
PUBLISH_DOCKERIO: "false" | |
# Enable caching across builds, set to "" to disable | |
CACHE_FROM: type=gha | |
CACHE_TO: type=gha,mode=max | |
jobs: | |
tag: | |
runs-on: ubuntu-22.04 | |
timeout-minutes: 2 | |
outputs: | |
existing-tags: ${{ steps.quayio.outputs.tags }} | |
new-tag: ${{ steps.new.outputs.TAG }} | |
jupyterhub-version: ${{ steps.version.outputs.VERSION }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: JupyterHub version | |
id: version | |
run: | | |
VERSION=$(grep '^jupyterhub==' base/requirements.txt | cut -d= -f3) | |
if [[ $VERSION =~ [0-9]+\.[0-9]+\.[0-9]+ ]]; then | |
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT | |
else | |
echo "Failed to get JupyterHub version" | |
exit 1 | |
fi | |
- name: Get build-number by looking at existing tags | |
id: quayio | |
uses: manics/action-get-quayio-tags@main | |
with: | |
repository: ${{ env.IMAGE }} | |
version: ${{ steps.version.outputs.VERSION }} | |
# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/accessing-contextual-information-about-workflow-runs#github-context | |
# If this is not LATEST_BRANCH, nor is it a pull request against LATEST_BRANCH | |
# assume it's a backport branch which means we need to get all tags to work out | |
# which MAJOR and MAJOR.MINOR aliases are needed. | |
allTags: ${{ (github.ref != format('refs/heads/{0}', env.LATEST_BRANCH)) && (github.base_ref != format('refs/heads/{0}', env.LATEST_BRANCH)) }} | |
strict: "true" | |
- name: Get new tag | |
id: new | |
run: | | |
echo "TAG=${{ steps.version.outputs.VERSION }}-${{ steps.quayio.outputs.buildNumber }}" >> $GITHUB_OUTPUT | |
publish-docker: | |
runs-on: ubuntu-22.04 | |
timeout-minutes: 30 | |
needs: | |
- tag | |
services: | |
# So that we can test this in PRs/branches | |
local-registry: | |
image: registry:2 | |
ports: | |
- 5000:5000 | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Should we push this image to a public registry? | |
run: | | |
if [ "${{ github.ref == format('refs/heads/{0}', env.PUBLISH_BRANCH) }}" = "true" ]; then | |
echo "REGISTRY=quay.io/" >> $GITHUB_ENV | |
echo "PUBLIC=true" >> $GITHUB_ENV | |
else | |
echo "REGISTRY=localhost:5000/" >> $GITHUB_ENV | |
echo "PUBLIC=false" >> $GITHUB_ENV | |
fi | |
- uses: actions/checkout@v4 | |
# Setup docker to build for multiple platforms, see: | |
# https://github.com/docker/build-push-action/tree/v6.9.0?tab=readme-ov-file#usage | |
# https://docs.docker.com/build/ci/github-actions/multi-platform/ | |
- name: Set up QEMU (for docker buildx) | |
uses: docker/setup-qemu-action@v3 | |
- name: Set up Docker Buildx (for multi-arch builds) | |
uses: docker/setup-buildx-action@v3 | |
with: | |
# Allows pushing to registry on localhost:5000 | |
driver-opts: network=host | |
- name: Setup push rights to Docker Hub | |
# This was setup by... | |
# 1. Creating a [Robot Account](https://quay.io/organization/jupyterhub?tab=robots) in the JupyterHub | |
# . Quay.io org | |
# 2. Giving it enough permissions to push to the jupyterhub and singleuser images | |
# 3. Putting the robot account's username and password in GitHub actions environment | |
if: env.PUBLIC == 'true' | |
run: | | |
docker login -u "${{ secrets.QUAY_USERNAME }}" -p "${{ secrets.QUAY_PASSWORD }}" "${{ env.REGISTRY }}" | |
if [ "${{ env.PUBLISH_DOCKERIO }}" = "true" ]; then | |
docker login -u "${{ secrets.DOCKERHUB_USERNAME }}" -p "${{ secrets.DOCKERHUB_TOKEN }}" docker.io | |
fi | |
# image: env.IMAGE | |
# | |
# https://github.com/jupyterhub/action-major-minor-tag-calculator | |
# If this is a tagged build this will return additional parent tags. | |
# E.g. 1.2.3 is expanded to Docker tags | |
# [{prefix}:1.2.3, {prefix}:1.2, {prefix}:1, {prefix}:latest] unless | |
# this is a backported tag in which case the newer tags aren't updated. | |
- name: Calculate tags | |
id: jupyterhubtags | |
uses: manics/action-major-minor-tag-calculator@allow-external-tag | |
with: | |
tagList: ${{ needs.tag.outputs.existing-tags }} | |
currentTag: ${{ needs.tag.outputs.new-tag }} | |
prefix: >- | |
${{ env.REGISTRY }}${{ env.IMAGE }}: | |
${{ (env.PUBLIC == 'true' && env.PUBLISH_DOCKERIO == 'true') && format('{0}:', env.IMAGE) || '' }} | |
- name: Print tags | |
run: | | |
echo "Existing tags: ${{ needs.tag.outputs.existing-tags }}" | |
echo "New tags: ${{ needs.tag.outputs.new-tag }}" | |
echo "Image tags: ${{ steps.jupyterhubtags.outputs.tags }}" | |
- name: Build and push jupyterhub | |
uses: docker/build-push-action@v6 | |
with: | |
context: base | |
platforms: linux/amd64,linux/arm64 | |
push: true | |
# tags parameter must be a string input so convert `gettags` JSON | |
# array into a comma separated list of tags | |
tags: ${{ join(fromJson(steps.jupyterhubtags.outputs.tags)) }} | |
cache-from: ${{ env.CACHE_FROM }} | |
cache-to: ${{ env.CACHE_TO }} | |
# image: env.IMAGE-onbuild | |
# | |
- name: Get list of jupyterhub-onbuild tags | |
id: onbuildtags | |
uses: manics/action-major-minor-tag-calculator@allow-external-tag | |
with: | |
tagList: ${{ needs.tag.outputs.existing-tags }} | |
currentTag: ${{ needs.tag.outputs.new-tag }} | |
prefix: >- | |
${{ env.REGISTRY }}${{ env.IMAGE }}-onbuild: | |
${{ (env.PUBLIC == 'true' && env.PUBLISH_DOCKERIO == 'true') && format('{0}-onbuild:', env.IMAGE) || '' }} | |
- name: Build and push jupyterhub-onbuild | |
uses: docker/build-push-action@v6 | |
with: | |
build-args: | | |
BASE_IMAGE=${{ fromJson(steps.jupyterhubtags.outputs.tags)[0] }} | |
context: onbuild | |
platforms: linux/amd64,linux/arm64 | |
push: true | |
tags: ${{ join(fromJson(steps.onbuildtags.outputs.tags)) }} | |
cache-from: ${{ env.CACHE_FROM }} | |
cache-to: ${{ env.CACHE_TO }} | |
# image: env.IMAGE-demo | |
# | |
- name: Get list of jupyterhub-demo tags | |
id: demotags | |
uses: manics/action-major-minor-tag-calculator@allow-external-tag | |
with: | |
tagList: ${{ needs.tag.outputs.existing-tags }} | |
currentTag: ${{ needs.tag.outputs.new-tag }} | |
prefix: >- | |
${{ env.REGISTRY }}${{ env.IMAGE }}-demo: | |
${{ (env.PUBLIC == 'true' && env.PUBLISH_DOCKERIO == 'true') && format('{0}-demo:', env.IMAGE) || '' }} | |
- name: Build and push jupyterhub-demo | |
uses: docker/build-push-action@v6 | |
with: | |
build-args: | | |
BASE_IMAGE=${{ fromJson(steps.onbuildtags.outputs.tags)[0] }} | |
context: demo-image | |
# linux/arm64 currently fails: | |
# ERROR: Could not build wheels for argon2-cffi which use PEP 517 and cannot be installed directly | |
# ERROR: executor failed running [/bin/sh -c python3 -m pip install notebook]: exit code: 1 | |
platforms: linux/amd64 | |
push: true | |
tags: ${{ join(fromJson(steps.demotags.outputs.tags)) }} | |
cache-from: ${{ env.CACHE_FROM }} | |
cache-to: ${{ env.CACHE_TO }} | |
# image: env.SINGLEUSER | |
# | |
- name: Get list of jupyterhub/singleuser tags | |
id: singleusertags | |
uses: manics/action-major-minor-tag-calculator@allow-external-tag | |
with: | |
tagList: ${{ needs.tag.outputs.existing-tags }} | |
currentTag: ${{ needs.tag.outputs.new-tag }} | |
prefix: >- | |
${{ env.REGISTRY }}${{ env.SINGLEUSER }}: | |
${{ (env.PUBLIC == 'true' && env.PUBLISH_DOCKERIO == 'true') && format('{0}:', env.SINGLEUSER) || '' }} | |
- name: Build and push jupyterhub/singleuser | |
uses: docker/build-push-action@v6 | |
with: | |
build-args: | | |
JUPYTERHUB_VERSION=${{ needs.tag.outputs.jupyterhub-version }} | |
context: singleuser | |
platforms: linux/amd64,linux/arm64 | |
push: true | |
tags: ${{ join(fromJson(steps.singleusertags.outputs.tags)) }} | |
cache-from: ${{ env.CACHE_FROM }} | |
cache-to: ${{ env.CACHE_TO }} |