diff --git a/.github/workflows/test-chart.yaml b/.github/workflows/test-chart.yaml index 0aba892..eabc97b 100644 --- a/.github/workflows/test-chart.yaml +++ b/.github/workflows/test-chart.yaml @@ -32,7 +32,7 @@ jobs: python-version: "3.11" - name: Install dependencies - run: pip install chartpress yamllint + run: pip install -r dev-requirements.txt - name: Lint and validate run: tools/templates/lint-and-validate.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 234e861..44d9c16 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -47,6 +47,7 @@ repos: rev: v3.0.0-alpha.6 hooks: - id: prettier + exclude: binderhub-service/templates/.* # Linting: Python code (see the file .flake8) - repo: https://github.com/PyCQA/flake8 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1333ed7 --- /dev/null +++ b/LICENSE @@ -0,0 +1 @@ +TODO diff --git a/README.md b/README.md index 9bf3320..2df013c 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# binderhub-service \ No newline at end of file +# binderhub-service diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 0000000..6d5d388 --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,48 @@ +# How to make a release + +`binderhub-service` is a Helm chart available in the Helm chart repository +`https://2i2c.org/binderhub-service`. + +## Pre-requisites + +- Push rights to [2i2c-org/binderhub-service] + +## Steps to make a release + +1. Create a PR updating `docs/source/changelog.md` with [github-activity] and + continue only when its merged. + + ```shell + pip install github-activity + + github-activity --heading-level=3 2i2c-org/binderhub-service + ``` + +1. Checkout main and make sure it is up to date. + + ```shell + git checkout main + git fetch origin main + git reset --hard origin/main + ``` + +1. Update the version, make commits, and push a git tag with `tbump`. + + ```shell + pip install tbump + tbump --dry-run ${VERSION} + + tbump ${VERSION} + ``` + + Following this, the [CI system] will build and publish a release. + +1. Reset the version back to dev, e.g. `1.1.0-0.dev` after releasing `1.0.0` + + ```shell + tbump --no-tag ${NEXT_VERSION}-0.dev + ``` + +[2i2c-org/binderhub-service]: https://github.com/2i2c-org/binderhub-service +[github-activity]: https://github.com/executablebooks/github-activity +[ci system]: https://github.com/2i2c-org/binderhub-service/actions/workflows/release.yaml diff --git a/binderhub-service/.helmignore b/binderhub-service/.helmignore index 0e8a0eb..1205485 100644 --- a/binderhub-service/.helmignore +++ b/binderhub-service/.helmignore @@ -1,3 +1,13 @@ +# Anything within the root folder of the Helm chart, where Chart.yaml resides, +# will be embedded into the packaged Helm chart. This is reasonable since only +# when the templates render after the chart has been packaged and distributed, +# will the templates logic evaluate that determines if other files were +# referenced, such as our our files/hub/jupyterhub_config.py. +# +# Here are files that we intentionally ignore to avoid them being packaged, +# because we don't want to reference them from our templates anyhow. +values.schema.yaml + # Patterns to ignore when building packages. # This supports shell glob matching, relative path matching, and # negation (prefixed with !). Only one pattern per line. diff --git a/binderhub-service/Chart.yaml b/binderhub-service/Chart.yaml index a3251f8..02aaa7a 100644 --- a/binderhub-service/Chart.yaml +++ b/binderhub-service/Chart.yaml @@ -1,24 +1,14 @@ +# Chart.yaml v2 reference: https://helm.sh/docs/topics/charts/#the-chartyaml-file apiVersion: v2 name: binderhub-service -description: A Helm chart for Kubernetes - -# A chart can be either an 'application' or a 'library' chart. -# -# Application charts are a collection of templates that can be packaged into versioned archives -# to be deployed. -# -# Library charts provide useful utilities or functions for the chart developer. They're included as -# a dependency of application charts to inject those utilities and functions into the rendering -# pipeline. Library charts do not define any templates and therefore cannot be deployed. -type: application - -# This is the chart version. This version number should be incremented each time you make changes -# to the chart and its templates, including the app version. -# Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 - -# This is the version number of the application being deployed. This version number should be -# incremented each time you make changes to the application. Versions are not expected to -# follow Semantic Versioning. They should reflect the version the application is using. -# It is recommended to use it with quotes. -appVersion: "1.16.0" +version: 0.0.1-set.by.chartpress +appVersion: "1.0.0" +description: A BinderHub installation separate from JupyterHub +keywords: [binderhub, binderhub-service, repo2docker, jupyterhub, jupyter] +home: https://2i2c.org/binderhub-service +sources: [https://github.com/2i2c-org/binderhub-service] +icon: https://binderhub.readthedocs.io/en/latest/_static/logo.png +kubeVersion: ">=1.23.0-0" +maintainers: + - name: Erik Sundell + email: erik@sundellopensource.se diff --git a/binderhub-service/templates/service.yaml b/binderhub-service/templates/service.yaml index 15a6b68..077592f 100644 --- a/binderhub-service/templates/service.yaml +++ b/binderhub-service/templates/service.yaml @@ -2,8 +2,7 @@ apiVersion: v1 kind: Service metadata: name: {{ include "binderhub-service.fullname" . }} - labels: - {{- include "binderhub-service.labels" . | nindent 4 }} + labels: {{- include "binderhub-service.labels" . | nindent 4 }} spec: type: {{ .Values.service.type }} ports: @@ -11,5 +10,4 @@ spec: targetPort: http protocol: TCP name: http - selector: - {{- include "binderhub-service.selectorLabels" . | nindent 4 }} + selector: {{- include "binderhub-service.selectorLabels" . | nindent 4 }} diff --git a/binderhub-service/values.schema.yaml b/binderhub-service/values.schema.yaml new file mode 100644 index 0000000..0522ae5 --- /dev/null +++ b/binderhub-service/values.schema.yaml @@ -0,0 +1,26 @@ +# This schema (a JSONSchema in YAML format) is used to generate +# values.schema.json to be packaged with the Helm chart. +# +# This schema is also planned to be used by our documentation system to build +# the configuration reference section based on the description fields. See +# docs/source/conf.py for that logic in the future! +# +# We look to document everything we have default values for in values.yaml, but +# we don't look to enforce the perfect validation logic within this file. +# +# ref: https://helm.sh/docs/topics/charts/#schema-files +# ref: https://json-schema.org/learn/getting-started-step-by-step.html +# +$schema: http://json-schema.org/draft-07/schema# +type: object +additionalProperties: true +required: + - global +properties: + nameOverride: + type: string + fullnameOverride: + type: string + global: + type: object + additionalProperties: true diff --git a/binderhub-service/values.yaml b/binderhub-service/values.yaml index a84bb5d..f4422f8 100644 --- a/binderhub-service/values.yaml +++ b/binderhub-service/values.yaml @@ -1,82 +1,60 @@ -# Default values for binderhub-service. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. +# General configuration +# ----------------------------------------------------------------------------- +# +nameOverride: "" +fullnameOverride: "" +global: {} +# Deployment resource +# ----------------------------------------------------------------------------- +# replicaCount: 1 image: - repository: nginx - pullPolicy: IfNotPresent - # Overrides the image tag whose default is the chart appVersion. - tag: "" + repository: quay.io/2i2c/binderhub-service + tag: "set-by-chartpress" + pullPolicy: "" + pullSecrets: [] +securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 +resources: {} -imagePullSecrets: [] -nameOverride: "" -fullnameOverride: "" +podAnnotations: {} +podSecurityContext: {} +nodeSelector: {} +tolerations: [] +affinity: {} +# ServiceAccount resource +# ----------------------------------------------------------------------------- +# serviceAccount: - # Specifies whether a service account should be created create: true - # Annotations to add to the service account annotations: {} - # The name of the service account to use. - # If not set and create is true, a name is generated using the fullname template name: "" -podAnnotations: {} - -podSecurityContext: {} - # fsGroup: 2000 - -securityContext: {} - # capabilities: - # drop: - # - ALL - # readOnlyRootFilesystem: true - # runAsNonRoot: true - # runAsUser: 1000 - +# Service resource +# ----------------------------------------------------------------------------- +# service: type: ClusterIP port: 80 +# Ingress resource +# ----------------------------------------------------------------------------- +# ingress: enabled: false className: "" annotations: {} - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: "true" hosts: - host: chart-example.local paths: - path: / pathType: ImplementationSpecific tls: [] - # - secretName: chart-example-tls - # hosts: - # - chart-example.local - -resources: {} - # We usually recommend not to specify default resources and to leave this as a conscious - # choice for the user. This also increases chances charts run on environments with little - # resources, such as Minikube. If you do want to specify resources, uncomment the following - # lines, adjust them as necessary, and remove the curly braces after 'resources:'. - # limits: - # cpu: 100m - # memory: 128Mi - # requests: - # cpu: 100m - # memory: 128Mi - -autoscaling: - enabled: false - minReplicas: 1 - maxReplicas: 100 - targetCPUUtilizationPercentage: 80 - # targetMemoryUtilizationPercentage: 80 - -nodeSelector: {} - -tolerations: [] - -affinity: {} diff --git a/chartpress.yaml b/chartpress.yaml index 0538317..4eb593e 100644 --- a/chartpress.yaml +++ b/chartpress.yaml @@ -20,4 +20,4 @@ charts: # binderhub-service, the container where the binderhub the Python # application is running. binderhub-service: - valuesPath: binderhub.image + valuesPath: image diff --git a/dev-requirements.txt b/dev-requirements.txt index 423bcad..4d16ff9 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -7,9 +7,11 @@ # chartpress -# pytest run tests that require requests and pyyaml +# pytest is used to run tests pytest + +# pyyaml is used by script under tools/ pyyaml -# tbump is making releases -tbump +# yamllint is used by tools/templates/lint-and-validate.py script +yamllint diff --git a/images/binderhub-service/requirements.txt b/images/binderhub-service/requirements.txt index 40e2f44..6bfd16d 100644 --- a/images/binderhub-service/requirements.txt +++ b/images/binderhub-service/requirements.txt @@ -4,7 +4,7 @@ # # Use the "Run workflow" button at https://github.com/2i2c-org/binderhub-service/actions/workflows/watch-dependencies.yaml # -alembic==1.10.0 +alembic==1.10.1 # via jupyterhub async-generator==1.10 # via jupyterhub diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..c2ffcd9 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,83 @@ +# NOTE: This github repository houses a Helm chart and some Python based scripts +# - not a python package. This file is only used to provide configuration +# for misc Python based utilities. +# + +# autoflake is used for autoformatting Python code +# +# ref: https://github.com/PyCQA/autoflake#readme +# +[tool.autoflake] +ignore-init-module-imports = true +remove-all-unused-imports = true +remove-duplicate-keys = true +remove-unused-variables = true + + +# isort is used for autoformatting Python code +# +# ref: https://pycqa.github.io/isort/ +# +[tool.isort] +profile = "black" + + +# black is used for autoformatting Python code +# +# ref: https://black.readthedocs.io/en/stable/ +# +[tool.black] +target_version = [ + "py310", + "py311", +] + + +# pytest is used for running Python based tests +# +# ref: https://docs.pytest.org/en/stable/ +# +[tool.pytest.ini_options] +addopts = "--verbose --color=yes --durations=10" +asyncio_mode = "auto" + + +# tbump is a tool to update version fields that we use +# to update baseVersion in chartpress.yaml as documented +# in RELEASE.md +# +# Config reference: https://github.com/your-tools/tbump#readme +# +[tool.tbump] +github_url = "https://github.com/2i2c-org/binderhub-service" + +[tool.tbump.version] +current = "0.1.0-0.dev" + +# match our prerelease prefixes +# -alpha.1 +# -beta.2 +# -0.dev +regex = ''' + (?P\d+) + \. + (?P\d+) + \. + (?P\d+) + (\- + (?P + ( + (alpha|beta|rc)\.\d+| + 0\.dev + ) + ) + )? +''' + +[tool.tbump.git] +message_template = "Bump to {new_version}" +tag_template = "{new_version}" + +[[tool.tbump.file]] +src = "chartpress.yaml" +search = 'baseVersion: "{current_version}"' diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..f3d5fee --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,6 @@ +""" +conftest.py is read by pytest automatically and can be used to declare fixtures +referenced by test functions. + +ref: https://docs.pytest.org/en/latest/writing_plugins.html#conftest-py-plugins +""" diff --git a/tools/generate-json-schema.py b/tools/generate-json-schema.py index bf11166..929e36b 100755 --- a/tools/generate-json-schema.py +++ b/tools/generate-json-schema.py @@ -16,7 +16,9 @@ import yaml here_dir = os.path.abspath(os.path.dirname(__file__)) -schema_yaml = os.path.join(here_dir, os.pardir, "binderhub-service", "values.schema.yaml") +schema_yaml = os.path.join( + here_dir, os.pardir, "binderhub-service", "values.schema.yaml" +) values_schema_json = os.path.join( here_dir, os.pardir, "binderhub-service", "values.schema.json" ) diff --git a/tools/templates/lint-and-validate-values.yaml b/tools/templates/lint-and-validate-values.yaml index e69de29..490a0b7 100644 --- a/tools/templates/lint-and-validate-values.yaml +++ b/tools/templates/lint-and-validate-values.yaml @@ -0,0 +1 @@ +global: {} diff --git a/tools/templates/lint-and-validate.py b/tools/templates/lint-and-validate.py index 05b1b2f..6d574d6 100755 --- a/tools/templates/lint-and-validate.py +++ b/tools/templates/lint-and-validate.py @@ -47,7 +47,7 @@ def lint(yamllint_config, values, output_dir, strict, debug): print("### Linting started") print("### 1/3 - helm lint: lint helm templates") - helm_lint_cmd = ["helm", "lint", "../../jupyterhub", f"--values={values}"] + helm_lint_cmd = ["helm", "lint", "../../binderhub-service", f"--values={values}"] if strict: helm_lint_cmd.append("--strict") if debug: @@ -58,7 +58,7 @@ def lint(yamllint_config, values, output_dir, strict, debug): helm_template_cmd = [ "helm", "template", - "../../jupyterhub", + "../../binderhub-service", f"--values={values}", f"--output-dir={output_dir}", ] diff --git a/tools/validate-against-schema.py b/tools/validate-against-schema.py index 8599e17..4e12cf5 100755 --- a/tools/validate-against-schema.py +++ b/tools/validate-against-schema.py @@ -5,7 +5,9 @@ import yaml here_dir = os.path.abspath(os.path.dirname(__file__)) -schema_yaml = os.path.join(here_dir, os.pardir, "binderhub-service", "values.schema.yaml") +schema_yaml = os.path.join( + here_dir, os.pardir, "binderhub-service", "values.schema.yaml" +) values_yaml = os.path.join(here_dir, os.pardir, "binderhub-service", "values.yaml") lint_and_validate_values_yaml = os.path.join( here_dir, "templates", "lint-and-validate-values.yaml"