Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 141 additions & 0 deletions .agents/skills/add-to-release-please/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
---
name: add-to-release-please
description: >-
Register a package in release-please by updating release-please-config.json
and .release-please-manifest.json, and aligning publish workflows to the new
tag prefix. Use when adding an app, Helm chart, or package to release-please,
onboarding a new release path, or when the user mentions release-please
config or manifest.
---

# Add to release-please

Register a package so release-please can version it, write changelogs, and create tags/releases.

## When to Use

- Adding an app, library, or Helm chart to release-please
- Onboarding a new release path in this monorepo
- Updating release-please config or manifest for a new package

## Instructions

### 1. Work out the path

Work out the path to use, or ask the user what path to use.

The path is the package key in both config files (repo-relative directory). Confirm it exists and is not already in `release-please-config.json`.

| Kind | Path examples |
|---|---|
| App | `cogstack-cohorter` |
| Helm chart | `helm-charts/medcat-service-helm` |

Helm charts in this repo are top-level directories under `helm-charts/<chart>/` with a `Chart.yaml`. The package key is that directory. See [Helm charts](#helm-charts) before editing.

### 2. Update `release-please-config.json`

Update `release-please-config.json` with the path. Work out the release-type. It's probably `python`, `helm`, `node`, or `simple`.

Add under `packages`. Match the file's 4-space indent.

```json
"<path>": {
"release-type": "<python|node|helm|simple>",
"component": "<tag-prefix>",
"changelog-path": "CHANGELOG.md",
"bump-minor-pre-major": false,
"bump-patch-for-minor-pre-major": false,
"draft": false,
"prerelease": false
}
```

**`release-type`:**

| Type | When | Bumps |
|---|---|---|
| `python` | Root `pyproject.toml` | `$.project.version` |
| `node` | Root `package.json` | `version` |
| `helm` | Chart dir with `Chart.yaml` | `version` |
| `simple` | No single root version file, or nested API + frontend | CHANGELOG only; use `extra-files` for nested bumps |

`component` is the git tag prefix: `{component}-v{version}` (e.g. `cohorter-v0.7.0`). For Helm charts in this repo, `component` is the package path (`helm-charts/<chart>`), so the tag is `helm-charts/<chart>-v<version>`.

**`extra-files`** (paths relative to the package directory) — e.g. python API + node frontend under `simple`:

```json
"extra-files": [
{
"type": "toml",
"path": "api/pyproject.toml",
"jsonpath": "$.project.version"
},
{
"type": "json",
"path": "frontend/package.json",
"jsonpath": "$.version"
}
]
```

### Helm charts

Copy an existing chart entry such as `helm-charts/medcat-service-helm`. Charts here always use `release-type` `helm`, `component` equal to the package key, and these changelog sections. Do not add `extra-files`.

`<chart>` is the directory name (for example `ocr-service-helm`). It must match `name` in `Chart.yaml`, and `Chart.yaml` must sit directly under `helm-charts/` (not nested).

```json
"helm-charts/<chart>": {
"release-type": "helm",
"component": "helm-charts/<chart>",
"changelog-path": "CHANGELOG.md",
"bump-minor-pre-major": false,
"bump-patch-for-minor-pre-major": false,
"draft": false,
"prerelease": false,
"changelog-sections": [
{ "type": "feat", "section": "Features" },
{ "type": "fix", "section": "Bug Fixes" },
{ "type": "build", "section": "Dependencies" },
{ "type": "refactor", "section": "Code Refactoring" },
{ "type": "revert", "section": "Reverts" }
]
}
```

`.github/workflows/kubernetes-charts-build.yaml` already discovers every `helm-charts/*/Chart.yaml` and publishes tags matching `helm-charts/*-v*.*.*`. Do not add a workflow or edit `release-please.yml` for a chart that fits this layout. Release-please writes `CHANGELOG.md` on the first release.

### 3. Update `.release-please-manifest.json`

Update `.release-please-manifest.json` by finding the most recent version based on the tags in git.

The manifest value is the **last released** version. The next tag is a bump from that version (`0.1.0` plus a `feat` commit becomes `0.2.0`).

1. `git tag -l '*<name>*' | sort -V`
2. Take the highest semver; strip the prefix (`helm-charts/medcat-service-helm-v0.6.0` → `0.6.0`)
3. If the user states a version, confirm it against git tags
4. If tags exist, add `"<path>": "<version>"` (same path key as in the config)
5. If there are no tags, the package has never been released. Set the manifest to `0.0.0` and set `initial-version` on the package to the first tag you want (for example `"initial-version": "0.1.0"`). `0.0.0` is not treated as a prior release, so the first release is `initial-version` rather than a bump. Without `initial-version`, that first release defaults to `1.0.0`. Do not copy `Chart.yaml` `version` into the manifest for an unreleased chart.

### 4. Update GitHub workflows if the tag format changes

Skip this step for a Helm chart registered as in [Helm charts](#helm-charts). The shared chart workflow already matches `helm-charts/*-v*.*.*`.

For other packages, release-please tags are `{component}-v{version}`. If workflows still match an old prefix that uses a forward slash (e.g. `cogstack-cohorter/v*`):

1. `on.push.tags` → `{component}-v*`
2. Version strip / docker metadata patterns → after `{component}-v`
3. Attach artifacts to the release-please GitHub Release (do not create a draft release)

```bash
rg -n '<old-prefix>|tags:' .github/workflows/<package>*
```

### Done when

- [ ] Path chosen (or confirmed with user)
- [ ] `packages` entry in `release-please-config.json`
- [ ] Helm charts use the path, `component`, and `changelog-sections` from [Helm charts](#helm-charts)
- [ ] Manifest entry is the latest git tag, or `0.0.0` plus `initial-version` when the package has never been released
- [ ] Workflows updated if the tag prefix changed, except Helm charts that already match `helm-charts/*-v*.*.*`
3 changes: 2 additions & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"helm-charts/cogstack-ce-helm": "0.5.0",
"helm-charts/cogstack-cohorter-helm": "0.4.1",
"helm-charts/cogstack-observability-helm": "0.4.1",
"helm-charts/cogstack-jupyterhub-helm": "0.4.1"
"helm-charts/cogstack-jupyterhub-helm": "0.4.1",
"helm-charts/ocr-service-helm": "0.0.0"
}
1 change: 1 addition & 0 deletions docs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ nav:
- Cogstack CE Helm: platform/deployment/helm/charts/cogstack-ce-helm.md
- MedCAT Service Helm: platform/deployment/helm/charts/medcat-service-helm.md
- MedCAT Trainer Helm: platform/deployment/helm/charts/medcat-trainer-helm.md
- OCR Service Helm: platform/deployment/helm/charts/ocr-service-helm.md
- Cogstack Cohorter Helm: platform/deployment/helm/charts/cogstack-cohorter-helm.md
- Cogstack Observability Helm: platform/deployment/helm/charts/cogstack-observability-helm.md
- Cogstack JupyterHub Helm: platform/deployment/helm/charts/cogstack-jupyterhub-helm.md
Expand Down
3 changes: 1 addition & 2 deletions helm-charts/cogstack-ce-helm/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# CogStack Community Edition Helm Chart

This is a all in one helm chart that runs CogStack on Kubernetes. <br>
Description for Community Edition (CogStack CE) can be found [here](../../../../cogstack-ce/_index.md)
This is a all in one helm chart that runs CogStack on Kubernetes

## Overview

Expand Down
2 changes: 2 additions & 0 deletions helm-charts/cogstack-ce-helm/README.md.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

This is a all in one helm chart that runs CogStack on Kubernetes

The description for Community Edition (CogStack CE) can be found [here](../../../../cogstack-ce/_index.md)

## Overview

This chart is an umbrella chart that deploys:
Expand Down
2 changes: 1 addition & 1 deletion helm-charts/cogstack-cohorter-helm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ For issues and questions, please visit the [CogStack GitHub repository](https://

| Repository | Name | Version |
|------------|------|---------|
| https://otwld.github.io/ollama-helm/ | ollama(ollama) | >=0.1.0 |
| https://otwld.github.io/ollama-helm/ | ollama(ollama) | 1.54.0 |
| oci://registry-1.docker.io/cogstacksystems | medcat(medcat-service-helm) | 0.0.1 |

## Values
Expand Down
23 changes: 23 additions & 0 deletions helm-charts/ocr-service-helm/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
41 changes: 41 additions & 0 deletions helm-charts/ocr-service-helm/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
apiVersion: v2
name: ocr-service-helm
description: A Helm chart to deploy CogStack OCR Service

# 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.1.1"

keywords:
- cogstack
- ocr
- rest-api

home: https://docs.cogstack.org/
sources:
- https://github.com/CogStack/cogstack-platform
- https://github.com/CogStack/cogstack-ocr-service

maintainers:
- name: vladd-bit
email: 62345326+vladd-bit@users.noreply.github.com
url: https://github.com/CogStack

icon: "https://avatars.githubusercontent.com/u/28688163"
123 changes: 123 additions & 0 deletions helm-charts/ocr-service-helm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# ocr-service Helm Chart

A Helm chart to deploy CogStack OCR Service

**Homepage:** <https://docs.cogstack.org/>

## Installation

```sh
helm install ocr-service oci://registry-1.docker.io/cogstacksystems/ocr-service-helm
```

## Usage
For local testing, by default you can port forward the service using this command:

```sh
kubectl port-forward svc/ocr-service 8090:8090
```

Then navigate to http://localhost:8090 to try the service. You can also use http://localhost:8090/docs to view the REST APIs

## Configuration

To configure the service, create a values.yaml file and install with helm.

## Values

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| affinity | object | `{}` | |
| autoscaling.enabled | bool | `false` | |
| autoscaling.maxReplicas | int | `100` | |
| autoscaling.minReplicas | int | `1` | |
| autoscaling.targetCPUUtilizationPercentage | int | `80` | |
| env.OCR_SERVICE_CONVERTER_THREADS | string | `"1"` | |
| env.OCR_SERVICE_CPU_THREADS | string | `"1"` | |
| env.OCR_SERVICE_DEBUG_MODE | string | `"false"` | |
| env.OCR_SERVICE_GUNICORN_GRACEFUL_TIMEOUT | string | `"30"` | |
| env.OCR_SERVICE_GUNICORN_LOG_FILE_PATH | string | `"-"` | |
| env.OCR_SERVICE_GUNICORN_LOG_LEVEL | string | `"info"` | |
| env.OCR_SERVICE_GUNICORN_MAX_REQUESTS | string | `"50000"` | |
| env.OCR_SERVICE_GUNICORN_MAX_REQUESTS_JITTER | string | `"5000"` | |
| env.OCR_SERVICE_GUNICORN_TIMEOUT | string | `"300"` | |
| env.OCR_SERVICE_HOST | string | `"0.0.0.0"` | |
| env.OCR_SERVICE_IMAGE_DPI | string | `"200"` | |
| env.OCR_SERVICE_LIBRE_OFFICE_PROCESS_TIMEOUT | string | `"20"` | |
| env.OCR_SERVICE_LOG_LEVEL | string | `"20"` | |
| env.OCR_SERVICE_OPERATION_MODE | string | `"OCR"` | |
| env.OCR_SERVICE_PORT | string | `"8090"` | |
| env.OCR_SERVICE_TESSERACT_CUSTOM_CONFIG_FLAGS | string | `""` | |
| env.OCR_SERVICE_TESSERACT_LANG | string | `"eng"` | |
| env.OCR_SERVICE_TESSERACT_NICE | string | `"-18"` | |
| env.OCR_SERVICE_TESSERACT_TIMEOUT | string | `"30"` | |
| env.OCR_SERVICE_WORKER_CLASS | string | `"sync"` | |
| env.OCR_TMP_DIR | string | `"/ocr_service/tmp"` | |
| env.OCR_WEB_SERVICE_WORKERS | string | `"1"` | |
| envValueFrom | object | `{"K8S_NODE_NAME":{"fieldRef":{"fieldPath":"spec.nodeName"}},"K8S_POD_NAME":{"fieldRef":{"fieldPath":"metadata.name"}},"K8S_POD_NAMESPACE":{"fieldRef":{"fieldPath":"metadata.namespace"}},"K8S_POD_UID":{"fieldRef":{"fieldPath":"metadata.uid"}}}` | Allow setting env values from field/configmap/secret references. Defaults to include k8s details for observability. |
| extraInitContainers | list | `[]` | Additional init containers to run before the main container. Can be templated |
| extraManifests | list | `[]` | Additional manifests to deploy to kubernetes. Can be templated |
| fullnameOverride | string | `""` | |
| hostAliases | list | `[]` | Host aliases for the pod |
| httpRoute | object | `{"annotations":{},"enabled":false,"hostnames":["chart-example.local"],"parentRefs":[{"name":"gateway","sectionName":"http"}],"rules":[{"matches":[{"path":{"type":"PathPrefix","value":"/headers"}}]}]}` | Expose the service via gateway-api HTTPRoute Requires Gateway API resources and suitable controller installed within the cluster (see: https://gateway-api.sigs.k8s.io/guides/) |
| image | object | `{"pullPolicy":"IfNotPresent","repository":"cogstacksystems/cogstack-ocr-service"}` | This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/ |
| image.pullPolicy | string | `"IfNotPresent"` | This sets the pull policy for images. |
| image.repository | string | `"cogstacksystems/cogstack-ocr-service"` | Image repository for the MedCAT service container |
| imagePullSecrets | list | `[]` | This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ |
| ingress.annotations | object | `{}` | |
| ingress.className | string | `""` | |
| ingress.enabled | bool | `false` | |
| ingress.hosts[0].host | string | `"chart-example.local"` | |
| ingress.hosts[0].paths[0].path | string | `"/"` | |
| ingress.hosts[0].paths[0].pathType | string | `"ImplementationSpecific"` | |
| ingress.tls | list | `[]` | |
| livenessProbe.failureThreshold | int | `3` | |
| livenessProbe.httpGet.path | string | `"/api/health"` | |
| livenessProbe.httpGet.port | string | `"http"` | |
| livenessProbe.initialDelaySeconds | int | `30` | |
| livenessProbe.periodSeconds | int | `30` | |
| livenessProbe.timeoutSeconds | int | `5` | |
| nameOverride | string | `""` | This is to override the chart name. |
| nodeSelector | object | `{}` | |
| podAnnotations | object | `{}` | This is for setting Kubernetes Annotations to a Pod. For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ |
| podLabels | object | `{}` | This is for setting Kubernetes Labels to a Pod. For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ |
| podSecurityContext.fsGroup | int | `10001` | |
| podSecurityContext.fsGroupChangePolicy | string | `"OnRootMismatch"` | |
| readinessProbe.failureThreshold | int | `6` | |
| readinessProbe.httpGet.path | string | `"/api/ready"` | |
| readinessProbe.httpGet.port | string | `"http"` | |
| readinessProbe.initialDelaySeconds | int | `20` | |
| readinessProbe.periodSeconds | int | `10` | |
| readinessProbe.timeoutSeconds | int | `5` | |
| replicaCount | int | `1` | This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/ |
| resources | object | `{}` | Configure resources for the pod. More information can be found here: https://kubernetes.io/docs/concepts/containers/ Recommendation for a default production model is { requests: { cpu: 500m, memory: 512Mi }, limits: { cpu: null <unset>, memory: 1Gi } } |
| runtimeClassName | string | `""` | Runtime class name for the pod (e.g., "nvidia" for GPU workloads) More information: https://kubernetes.io/docs/concepts/containers/runtime-class/ |
| securityContext.allowPrivilegeEscalation | bool | `false` | |
| securityContext.capabilities.drop[0] | string | `"ALL"` | |
| securityContext.readOnlyRootFilesystem | bool | `false` | |
| securityContext.runAsGroup | int | `10001` | |
| securityContext.runAsNonRoot | bool | `true` | |
| securityContext.runAsUser | int | `10001` | |
| service.port | int | `8090` | This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports |
| service.type | string | `"ClusterIP"` | This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types |
| serviceAccount.annotations | object | `{}` | Annotations to add to the service account |
| serviceAccount.automount | bool | `true` | Automatically mount a ServiceAccount's API credentials? |
| serviceAccount.create | bool | `true` | Specifies whether a service account should be created |
| serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template |
| startupProbe.failureThreshold | int | `90` | |
| startupProbe.httpGet.path | string | `"/api/ready"` | |
| startupProbe.httpGet.port | string | `"http"` | |
| startupProbe.initialDelaySeconds | int | `2` | |
| startupProbe.periodSeconds | int | `10` | |
| startupProbe.timeoutSeconds | int | `5` | |
| tmp.emptyDir.medium | string | `""` | |
| tmp.emptyDir.sizeLimit | string | `"1Gi"` | |
| tmp.enabled | bool | `true` | |
| tmp.mountPath | string | `"/ocr_service/tmp"` | |
| tolerations | list | `[]` | |
| updateStrategy.type | string | `"RollingUpdate"` | Used for Kubernetes deployment .spec.strategy.type. Allowed values are "Recreate" or "RollingUpdate". |
| volumeMounts | list | `[]` | Additional volumeMounts on the output Deployment definition. |
| volumes | list | `[]` | Additional volumes on the output Deployment definition. |

----------------------------------------------
Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2)
Loading
Loading