Skip to content

Pin and automate doing isolated bumps of hub image dependencies' major versions #2659

Pin and automate doing isolated bumps of hub image dependencies' major versions

Pin and automate doing isolated bumps of hub image dependencies' major versions #2659

Workflow file for this run

# This is a GitHub workflow defining a set of jobs with a set of steps.
# ref: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions
#
name: Test chart
# Trigger the workflow's on all PRs and pushes so that other contributors can
# run tests in their own forks. Avoid triggering these tests on changes to
# documentation only changes.
on:
pull_request:
paths-ignore:
- "docs/**"
- "**.md"
- ".github/workflows/*"
- "!.github/workflows/test-chart.yaml"
push:
paths-ignore:
- "docs/**"
- "**.md"
- ".github/workflows/*"
- "!.github/workflows/test-chart.yaml"
branches-ignore:
- "dependabot/**"
- "pre-commit-ci-update-config"
- "update-*"
- "vuln-scan-*"
workflow_dispatch:
jobs:
lint_shell_scripts:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: pip install pre-commit
- name: Run all stages including shellcheck (disabled by default)
run: pre-commit run --all --hook-stage manual
lint_and_validate_rendered_templates:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: pip install chartpress yamllint
- name: Lint and validate
run: tools/templates/lint-and-validate.py
- name: Lint and validate (--strict, accept failure)
run: tools/templates/lint-and-validate.py --strict
continue-on-error: true
lint_and_validate_templates_with_schema:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
# We run this job with the latest lowest helm version we support.
#
# helm version 3.4.X is known to cause the following error in the named
# template "jupyterhub.imagePuller.daemonset.hook.checksum":
#
# error calling merge: reflect: call of reflect.Value.MapKeys on ptr Value
#
include:
- helm-version: "" # latest
- helm-version: v3.5.0 # minimal required version
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: |
. ci/common
setup_helm
pip install pyyaml
env:
HELM_VERSION: "${{ matrix.helm-version }}"
- name: Generate values.schema.json
run: tools/generate-json-schema.py
- name: Helm lint (values.yaml)
run: helm lint ./jupyterhub
- name: Helm lint (lint-and-validate-values.yaml)
run: helm lint ./jupyterhub --values tools/templates/lint-and-validate-values.yaml
# FIXME: We can probably emit a GitHub workflow warning if these fail
# instead having them show as green without a warning or similar
#
# NOTE: --strict means that any warning is considered an error, and there
# are several warnings that we should ignore.
#
- name: Helm lint --strict (values.yaml)
run: helm lint --strict ./jupyterhub
continue-on-error: true
- name: Helm lint --strict (lint-and-validate-values.yaml)
run: helm lint --strict ./jupyterhub
continue-on-error: true
test:
runs-on: ubuntu-22.04
timeout-minutes: 20
strategy:
# Keep running even if one variation of the job fail
fail-fast: false
matrix:
# We run this job multiple times with different parameterization
# specified below, these parameters have no meaning on their own and
# gain meaning on how job steps use them.
#
# k3s-version: https://github.com/rancher/k3s/tags
# k3s-channel: https://update.k3s.io/v1-release/channels
#
include:
- k3s-channel: latest
test: install
- k3s-channel: stable # also test hub-slim, and prePuller.hook
test: install
local-chart-extra-args: >-
--set hub.image.name=quay.io/jupyterhub/k8s-hub-slim
--set prePuller.hook.enabled=true
--set prePuller.hook.pullOnlyOnChanges=true
- k3s-channel: v1.31 # also test hub.existingSecret and subdomain_host
test: install
local-chart-extra-args: >-
--set hub.existingSecret=test-hub-existing-secret
--set proxy.secretToken=aaaa1111
--set hub.cookieSecret=bbbb2222
--set hub.config.CryptKeeper.keys[0]=cccc3333
--set hub.config.JupyterHub.subdomain_host=jupyterhub.example.org
create-k8s-test-resources: true
# We run three upgrade tests where we first install an already released
# Helm chart version and then upgrade to the version we are now
# testing:
# - latest stable version (like 1.2.3)
# - latest dev version (like 1.2.3-0.dev.git.5810.hf475e7a4),
# - and an old version that requires a JupyterHub DB upgrade
#
# It can be very useful to see the "Helm diff" step's output from the
# latest dev version.
#
# The upgrade-from input should be a chart version, or match the version
# information from
# https://hub.jupyter.org/helm-chart/info.json
#
- k3s-channel: v1.30
test: upgrade
upgrade-from: stable
upgrade-from-extra-args: >-
--set proxy.secretToken=aaaa1111
--set hub.cookieSecret=bbbb2222
--set hub.config.CryptKeeper.keys[0]=cccc3333
--set hub.db.type=sqlite-pvc
--set singleuser.storage.type=dynamic
local-chart-extra-args: >-
--set hub.db.type=sqlite-pvc
--set singleuser.storage.type=dynamic
create-k8s-test-resources: true
- k3s-channel: v1.29
test: upgrade
upgrade-from: dev
upgrade-from-extra-args: >-
--set proxy.secretToken=aaaa1111
--set hub.db.type=sqlite-pvc
--set singleuser.storage.type=dynamic
local-chart-extra-args: >-
--set hub.db.type=sqlite-pvc
--set singleuser.storage.type=dynamic
- k3s-channel: v1.28
test: upgrade
# We're testing hub.db.upgrade with PostgreSQL so this version must be old
# enough to require a DB upgrade
upgrade-from: 2.0.0
upgrade-from-extra-args: >-
--set proxy.secretToken=aaaa1111
--set hub.cookieSecret=bbbb2222
--set hub.config.CryptKeeper.keys[0]=cccc3333
--set hub.db.type=postgres
--set hub.db.url=postgresql+psycopg2://postgres:postgres@postgresql:5432/jupyterhub
--set singleuser.storage.type=dynamic
local-chart-extra-args: >-
--set hub.db.type=postgres
--set hub.db.url=postgresql+psycopg2://postgres:postgres@postgresql:5432/jupyterhub
--set singleuser.storage.type=dynamic
--set hub.db.upgrade=true
create-k8s-test-resources: true
# https://artifacthub.io/packages/helm/bitnami/postgresql
setup-postgresql-args: >-
--version=16.0.5
--set auth.enablePostgresUser=true
--set auth.postgresPassword=postgres
--set auth.database=jupyterhub
--set audit.logHostname=true
--set audit.logConnections=true
--set audit.logDisconnections=true
--set audit.clientMinMessages=debug
steps:
- uses: actions/checkout@v4
with:
# chartpress requires git history to set chart version and image tags
# correctly
fetch-depth: 0
# Starts a k8s cluster with NetworkPolicy enforcement and installs both
# kubectl and helm
#
# ref: https://github.com/jupyterhub/action-k3s-helm/
- uses: jupyterhub/action-k3s-helm@v4
with:
k3s-channel: ${{ matrix.k3s-channel }}
metrics-enabled: false
traefik-enabled: false
docker-enabled: true
- uses: actions/setup-python@v5
with:
python-version: "3.11"
# Install a local ACME server to fill the role of Let's Encrypt (LE). We
# do this as the HTTP challenge sent out by an ACME server must be able to
# reach the ACME client in our autohttps pod.
- name: Install local ACME server
run: |
helm install pebble --repo https://hub.jupyter.org/helm-chart/ pebble --values dev-config-pebble.yaml
# Build our images if needed and update values.yaml with the tags
- name: Install and run chartpress
run: |
pip3 install -r dev-requirements.txt
chartpress
env:
DOCKER_BUILDKIT: "1"
- name: Generate values.schema.json from values.schema.yaml
run: |
tools/generate-json-schema.py
# Validate rendered helm templates against the k8s api-server with the
# dedicated lint-and-validate-values.yaml config.
- name: "Helm template --validate (with lint and validate config)"
run: |
helm template --validate jupyterhub ./jupyterhub --values tools/templates/lint-and-validate-values.yaml ${{ matrix.helm-template-validate-extra-args }}
# It is only needed at this point forward as this is when we install
# jupyterhub and the autohttps pod is about to start, so for CI
# performance we delayed this until now and did other things in between.
- name: Await local ACME server
uses: jupyterhub/action-k8s-await-workloads@v3
with:
timeout: 150
max-restarts: 1
- name: "(Upgrade) Install PostgreSQL server chart"
if: matrix.setup-postgresql-args
run: |
. ./ci/common
helm install postgresql postgresql --repo=https://charts.bitnami.com/bitnami ${{ matrix.setup-postgresql-args }}
await_kubectl_rollout statefulset/postgresql
- name: "(Upgrade) Install ${{ matrix.upgrade-from }} chart"
if: matrix.test == 'upgrade'
run: |
# NOTE: We change the directory so jupyterhub the chart name won't be
# misunderstood as the local folder name.
#
# https://github.com/helm/helm/issues/9244
cd ci
if [ ${{ matrix.upgrade-from }} = stable ]; then
UPGRADE_FROM_VERSION=$(helm show chart --repo=https://hub.jupyter.org/helm-chart/ jupyterhub | yq e '.version' -)
elif [ ${{ matrix.upgrade-from }} = dev ]; then
UPGRADE_FROM_VERSION=$(helm show chart --devel --repo=https://hub.jupyter.org/helm-chart/ jupyterhub | yq e '.version' -)
else
UPGRADE_FROM_VERSION=${{ matrix.upgrade-from }}
fi
echo "UPGRADE_FROM_VERSION=$UPGRADE_FROM_VERSION" >> $GITHUB_ENV
echo ""
echo "Installing already released jupyterhub version $UPGRADE_FROM_VERSION"
helm install jupyterhub --repo https://hub.jupyter.org/helm-chart/ jupyterhub --values ../dev-config.yaml --version=$UPGRADE_FROM_VERSION ${{ matrix.upgrade-from-extra-args }}
- name: "(Upgrade) Install helm diff"
if: matrix.test == 'upgrade'
run: |
helm plugin install https://github.com/databus23/helm-diff
- name: "(Upgrade) Helm diff ${{ matrix.upgrade-from }} chart with local chart"
if: matrix.test == 'upgrade'
run: |
LOCAL_CHART_VERSION=$(cat jupyterhub/Chart.yaml | yq e '.version' -)
export STRING_REPLACER_A=$LOCAL_CHART_VERSION
export STRING_REPLACER_B=$UPGRADE_FROM_VERSION
echo "NOTE: Helm diff upgrade won't trigger lookup functions, so it"
echo " will look like we seed new passwords all the time."
echo
echo "NOTE: For the helm diff only, we have replaced the new chart"
echo " version with the old chart version to reduce clutter."
echo
echo " Old version: $UPGRADE_FROM_VERSION"
echo " New version: $LOCAL_CHART_VERSION (replaced)"
echo
helm diff upgrade --install jupyterhub ./jupyterhub --values dev-config.yaml \
--values dev-config-local-chart-extra-config.yaml \
${{ matrix.local-chart-extra-args }} \
--show-secrets \
--context=3 \
--post-renderer=ci/string-replacer.sh
- name: "(Upgrade) Await ${{ matrix.upgrade-from }} chart"
if: matrix.test == 'upgrade'
uses: jupyterhub/action-k8s-await-workloads@v3
with:
timeout: 150
max-restarts: 1
- name: "(Upgrade) Await ${{ matrix.upgrade-from }} chart cert acquisition"
if: matrix.test == 'upgrade'
run: |
. ./ci/common
await_autohttps_tls_cert_acquisition
await_autohttps_tls_cert_save
- name: Create k8s test resources
if: matrix.create-k8s-test-resources
run: |
kubectl apply -f ci/test-hub-existing-secret.yaml
- name: "Install local chart"
run: |
helm upgrade --install jupyterhub ./jupyterhub \
--values dev-config.yaml \
--values dev-config-local-chart-extra-config.yaml \
${{ matrix.local-chart-extra-args }}
- name: "Await local chart"
uses: jupyterhub/action-k8s-await-workloads@v3
with:
timeout: 150
max-restarts: 1
- name: Await local chart cert acquisition
run: |
. ./ci/common
await_autohttps_tls_cert_acquisition
- name: Run tests
continue-on-error: ${{ matrix.accept-failure == true }}
run: |
. ./ci/common
if [ "${{ contains(matrix.local-chart-extra-args, 'subdomain_host') }}" = "true" ]; then
export CI_SUBDOMAIN_HOST=jupyterhub.example.org
fi
# If you have problems with the tests add '--capture=no' to show stdout
pytest --verbose --maxfail=2 --color=yes ./tests
# ref: https://github.com/jupyterhub/action-k8s-namespace-report
- name: Kubernetes namespace report
uses: jupyterhub/action-k8s-namespace-report@v1
if: always()
with:
important-workloads: deploy/hub deploy/proxy
- name: Debug PostgreSQL logs on failure
if: failure() && matrix.setup-postgresql-args
run: |
kubectl logs statefulset/postgresql