Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
10 changes: 5 additions & 5 deletions .github/workflows/deploy-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ on:
description: 'IDE images tag (appdefinitions and preloading)'
required: false
default: 'latest'
helm_chart_branch:
description: 'Branch of theia-cloud-helm to use (leave empty for default)'
helm_chart_tag:
description: 'Preview OCI tag from theia-cloud-helm to use (for example pr-123)'
required: false
default: ''

Expand All @@ -49,7 +49,7 @@ jobs:
environment: test1
theia_cloud_tag: ${{ inputs.theia_cloud_tag || 'latest' }}
ide_images_tag: ${{ inputs.ide_images_tag || 'latest' }}
helm_chart_branch: ${{ inputs.helm_chart_branch || '' }}
helm_chart_tag: ${{ inputs.helm_chart_tag || '' }}
deploy_shared_gateway: false
shared_gateway_values_file: deployments/shared-gateway/values.yaml
shared_gateway_namespace: gateway-system
Expand All @@ -67,7 +67,7 @@ jobs:
environment: test2
theia_cloud_tag: ${{ inputs.theia_cloud_tag || 'latest' }}
ide_images_tag: ${{ inputs.ide_images_tag || 'latest' }}
helm_chart_branch: ${{ inputs.helm_chart_branch || '' }}
helm_chart_tag: ${{ inputs.helm_chart_tag || '' }}
deploy_shared_gateway: false
shared_gateway_values_file: deployments/shared-gateway/values.yaml
shared_gateway_namespace: gateway-system
Expand All @@ -85,7 +85,7 @@ jobs:
environment: test3
theia_cloud_tag: ${{ inputs.theia_cloud_tag || 'latest' }}
ide_images_tag: ${{ inputs.ide_images_tag || 'latest' }}
helm_chart_branch: ${{ inputs.helm_chart_branch || '' }}
helm_chart_tag: ${{ inputs.helm_chart_tag || '' }}
deploy_shared_gateway: false
shared_gateway_values_file: deployments/shared-gateway/values.yaml
shared_gateway_namespace: gateway-system
Expand Down
123 changes: 76 additions & 47 deletions .github/workflows/deploy-theia.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ on:
required: false
type: string
default: "latest"
helm_chart_branch:
description: "Branch of theia-cloud-helm to use (leave empty for main/published)"
helm_chart_tag:
description: "Published OCI preview tag to use for upstream helm charts (e.g. pr-123)"
required: false
type: string
default: ""
Expand All @@ -80,6 +80,7 @@ jobs:
name: Install Theia Cloud Helm Chart
permissions:
contents: read
packages: read
runs-on: ubuntu-latest
# Link to GitHub Environment for secrets and protection rules
environment: ${{ inputs.environment }}
Expand Down Expand Up @@ -114,55 +115,77 @@ jobs:
kubectl config get-contexts
kubectl get nodes

# Step 3.5: Checkout upstream Helm chart branch if specified
- name: Checkout Upstream Helm Branch
if: inputs.helm_chart_branch != ''
uses: actions/checkout@v4
with:
repository: EduIDE/EduIDE-Helm
ref: ${{ inputs.helm_chart_branch }}
path: upstream-helm

# Step 3.6: Patch Chart.yaml to use local upstream chart
- name: Patch Chart.yaml
if: inputs.helm_chart_branch != ''
- name: Patch Chart.yaml for OCI preview tag
if: inputs.helm_chart_tag != ''
run: |
echo "Patching Chart.yaml to use local upstream chart from branch: ${{ inputs.helm_chart_branch }}"

# Remove Chart.lock to force fresh dependency resolution
rm -f ./charts/theia-cloud-combined/Chart.lock

# Get the version from the local upstream chart
UPSTREAM_VERSION=$(grep '^version:' ./upstream-helm/charts/theia-cloud/Chart.yaml | head -1 | awk '{print $2}')
echo "Detected upstream chart version: $UPSTREAM_VERSION"

# Patch the repository URL to use local file path
sed -i 's|repository: "https://eduide.github.io/EduIDE-Helm"|repository: "file://../../upstream-helm/charts/theia-cloud"|' ./charts/theia-cloud-combined/Chart.yaml

# Patch the version to match the local chart's version exactly
sed -i "/name: theia-cloud/{n;s/version: .*/version: $UPSTREAM_VERSION/}" ./charts/theia-cloud-combined/Chart.yaml

echo "Patched Chart.yaml content:"
set -euo pipefail

get_theia_cloud_version() {
awk '
$1 == "-" && $2 == "name:" && $3 == "theia-cloud" { in_dep=1; next }
in_dep && $1 == "version:" { print $2; exit }
' ./charts/theia-cloud-combined/Chart.yaml
}

normalize_preview_version() {
local base="$1"
local tag="$2"
printf '%s.%s' "$base" "$tag"
}

THEIA_CLOUD_VERSION="$(get_theia_cloud_version)"
PREVIEW_VERSION="$(normalize_preview_version "$THEIA_CLOUD_VERSION" "${{ inputs.helm_chart_tag }}")"
sed -i "/name: theia-cloud/{n;s|version: .*|version: ${PREVIEW_VERSION}|;}" ./charts/theia-cloud-combined/Chart.yaml

echo "Using OCI preview version: ${PREVIEW_VERSION}"
cat ./charts/theia-cloud-combined/Chart.yaml

- name: Login to GHCR
env:
GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "$GHCR_TOKEN" | helm registry login ghcr.io -u "${{ github.actor }}" --password-stdin

# Step 4: Install Theia Cloud base components, CRDs, and cluster-wide monitoring
# These are prerequisites from the upstream Theia Cloud Helm repository
- name: Setup Helm dependencies
env:
KUBECONFIG: ${{ github.workspace }}/kubeconfig
run: |
# Add EduIDE Theia Cloud Helm repository
helm repo add theia-cloud-repo https://eduide.github.io/EduIDE-Helm/
helm repo update

# Update dependencies for our custom chart
helm dependency update ./charts/theia-cloud-combined
- name: Install Theia Cloud base and CRDs
env:
KUBECONFIG: ${{ github.workspace }}/kubeconfig
run: |
set -euo pipefail

THEIA_CLOUD_BASE_VERSION="1.4.0-next.0"
THEIA_CLOUD_CRDS_VERSION="1.2.0-next.0"

if [ -n "${{ inputs.helm_chart_tag }}" ]; then
normalize_preview_version() {
local base="$1"
local tag="$2"
printf '%s.%s' "$base" "$tag"
}

THEIA_CLOUD_BASE_VERSION="$(normalize_preview_version "$THEIA_CLOUD_BASE_VERSION" "${{ inputs.helm_chart_tag }}")"
THEIA_CLOUD_CRDS_VERSION="$(normalize_preview_version "$THEIA_CLOUD_CRDS_VERSION" "${{ inputs.helm_chart_tag }}")"
fi
THEIA_CLOUD_BASE_CHART=oci://ghcr.io/eduide/charts/theia-cloud-base
THEIA_CLOUD_CRDS_CHART=oci://ghcr.io/eduide/charts/theia-cloud-crds

# Install base components (operator base, metrics, etc.)
helm upgrade theia-cloud-base theia-cloud-repo/theia-cloud-base --install -n default -f ${{ vars.HELM_VALUES_PATH }}/theia-base-helm-values.yml
helm upgrade theia-cloud-base "$THEIA_CLOUD_BASE_CHART" --version "$THEIA_CLOUD_BASE_VERSION" --install -n default -f ${{ vars.HELM_VALUES_PATH }}/theia-base-helm-values.yml

# Install Custom Resource Definitions (CRDs) for Theia Cloud
helm upgrade theia-cloud-crds theia-cloud-repo/theia-cloud-crds --install -n default -f ${{ vars.HELM_VALUES_PATH }}/theia-crds-helm-values.yml
helm upgrade theia-cloud-crds "$THEIA_CLOUD_CRDS_CHART" --version "$THEIA_CLOUD_CRDS_VERSION" --install -n default -f ${{ vars.HELM_VALUES_PATH }}/theia-crds-helm-values.yml

- name: Install cluster-wide monitoring
env:
KUBECONFIG: ${{ github.workspace }}/kubeconfig
run: |

# Install cluster-wide monitoring (PodMonitors + Grafana Dashboards)
# This is installed once per cluster, not per environment
Expand All @@ -176,12 +199,18 @@ jobs:
SHARED_GATEWAY_VALUES_FILE: ${{ inputs.shared_gateway_values_file }}
SHARED_GATEWAY_NAMESPACE: ${{ inputs.shared_gateway_namespace }}
run: |
set -euo pipefail

SHARED_GATEWAY_NAMESPACE="${SHARED_GATEWAY_NAMESPACE:-gateway-system}"
echo "${{ secrets.THEIA_WILDCARD_CERTIFICATE_CERT }}" | base64 -w 0 > shared-gateway-wildcard.crt
echo "${{ secrets.THEIA_WILDCARD_CERTIFICATE_KEY }}" | base64 -w 0 > shared-gateway-wildcard.key

helm upgrade --install theia-shared-gateway ./charts/theia-shared-gateway \
--namespace "$SHARED_GATEWAY_NAMESPACE" \
--create-namespace \
-f "$SHARED_GATEWAY_VALUES_FILE"
-f "$SHARED_GATEWAY_VALUES_FILE" \
--set wildcardTLSSecret.certificate="$(cat shared-gateway-wildcard.crt)" \
--set wildcardTLSSecret.key="$(cat shared-gateway-wildcard.key)"

# Step 6: Install the main Theia Cloud application with environment-specific configuration
# This includes the operator, service, certificates, and app definitions
Expand Down Expand Up @@ -209,14 +238,14 @@ jobs:
--set theia-certificates.wildcardCertificate="$(cat wildcard.crt)" \
--set theia-certificates.wildcardKey="$(cat wildcard.key)" \
--set theia-cloud.keycloak.cookieSecret="${{ secrets.THEIA_KEYCLOAK_COOKIE_SECRET }}" \
--set theia-cloud.landingPage.image="ghcr.io/ls1intum/theia/landing-page:${THEIA_CLOUD_TAG}" \
--set theia-cloud.operator.image="ghcr.io/ls1intum/theia/operator:${THEIA_CLOUD_TAG}" \
--set theia-cloud.service.image="ghcr.io/ls1intum/theia/service:${THEIA_CLOUD_TAG}" \
--set "theia-cloud.preloading.images[0]=ghcr.io/ls1intum/theia/landing-page:${THEIA_CLOUD_TAG}" \
--set "theia-cloud.preloading.images[1]=ghcr.io/ls1intum/theia/java-17:${IDE_IMAGES_TAG}" \
--set "theia-cloud.preloading.images[2]=ghcr.io/ls1intum/theia/c:${IDE_IMAGES_TAG}" \
--set "theia-cloud.preloading.images[3]=ghcr.io/ls1intum/theia/javascript:${IDE_IMAGES_TAG}" \
--set "theia-cloud.preloading.images[4]=ghcr.io/ls1intum/theia/ocaml:${IDE_IMAGES_TAG}" \
--set "theia-cloud.preloading.images[5]=ghcr.io/ls1intum/theia/rust:${IDE_IMAGES_TAG}" \
--set "theia-cloud.preloading.images[6]=ghcr.io/ls1intum/theia/python:${IDE_IMAGES_TAG}" \
--set theia-cloud.landingPage.image="ghcr.io/eduide/eduide-cloud/landing-page:${THEIA_CLOUD_TAG}" \
--set theia-cloud.operator.image="ghcr.io/eduide/eduide-cloud/operator:${THEIA_CLOUD_TAG}" \
--set theia-cloud.service.image="ghcr.io/eduide/eduide-cloud/service:${THEIA_CLOUD_TAG}" \
--set "theia-cloud.preloading.images[0]=ghcr.io/eduide/eduide-cloud/landing-page:${THEIA_CLOUD_TAG}" \
--set "theia-cloud.preloading.images[1]=ghcr.io/eduide/eduide/java-17:${IDE_IMAGES_TAG}" \
--set "theia-cloud.preloading.images[2]=ghcr.io/eduide/eduide/c:${IDE_IMAGES_TAG}" \
--set "theia-cloud.preloading.images[3]=ghcr.io/eduide/eduide/javascript:${IDE_IMAGES_TAG}" \
--set "theia-cloud.preloading.images[4]=ghcr.io/eduide/eduide/ocaml:${IDE_IMAGES_TAG}" \
--set "theia-cloud.preloading.images[5]=ghcr.io/eduide/eduide/rust:${IDE_IMAGES_TAG}" \
--set "theia-cloud.preloading.images[6]=ghcr.io/eduide/eduide/python:${IDE_IMAGES_TAG}" \
--set theia-appdefinitions.defaultImageTag="${IDE_IMAGES_TAG}"
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +129,12 @@ Configuration files for each environment are located in the [deployments/](deplo

2. **Install Theia Cloud base charts**:
```bash
helm repo add theia-cloud-repo https://eclipse-theia.github.io/theia-cloud-helm/
helm repo update
helm registry login ghcr.io

helm upgrade theia-cloud-base theia-cloud-repo/theia-cloud-base --install \
helm upgrade theia-cloud-base oci://ghcr.io/eduide/charts/theia-cloud-base --version 1.2.0-next.0 --install \
-f deployments/your-environment/theia-base-helm-values.yml

helm upgrade theia-cloud-crds theia-cloud-repo/theia-cloud-crds --install \
helm upgrade theia-cloud-crds oci://ghcr.io/eduide/charts/theia-cloud-crds --version 1.2.0-next.0 --install \
-f deployments/your-environment/theia-crds-helm-values.yml
```

Expand All @@ -150,11 +149,16 @@ Configuration files for each environment are located in the [deployments/](deplo

4. **Install the combined Theia Cloud chart**:
```bash
helm registry login ghcr.io
helm upgrade --install theia-cloud-combined ./charts/theia-cloud-combined \
--namespace your-namespace --create-namespace \
-f deployments/your-environment/values.yaml
```

Normal deployments consume released OCI charts from `ghcr.io/eduide/charts`.
The `theia-cloud` dependency version in `charts/theia-cloud-combined/Chart.yaml` controls the main application chart, while `theia-cloud-base` and `theia-cloud-crds` are pinned separately in the workflow at `1.2.0-next.0` and `1.4.0-next.0`.
For PR previews, you can set `helm_chart_tag` to a value like `pr-123` to pull preview OCI charts published from `theia-cloud-helm` pull requests as versions such as `<chart-version>.pr-123`.

When using GitHub Actions, shared-gateway settings are passed as hardcoded inputs
by the caller workflows (`deploy-pr.yml`, `deploy-staging.yml`, `deploy-production.yml`):
- `deploy_shared_gateway` (`true`/`false`)
Expand Down
2 changes: 1 addition & 1 deletion charts/theia-appdefinitions/templates/appdefinition.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ metadata:
helm.sh/revision: {{ $.Release.Revision | quote }}
spec:
name: {{ .name }}
image: {{ .image | default "ghcr.io/ls1intum/theia/default" }}:{{ .imageTag | default $.Values.defaultImageTag | default "latest" }}
image: {{ .image | default "ghcr.io/eduide/eduide/default" }}:{{ .imageTag | default $.Values.defaultImageTag | default "latest" }}
uid: {{ .uid | default 101 }}
port: {{ .port | default 3000 }}
ingressname: {{ .ingressname | default "theia-cloud-demo-ws-route" }}
Expand Down
12 changes: 6 additions & 6 deletions charts/theia-appdefinitions/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defaultImageTag: latest

apps:
- name: java-17-latest
image: ghcr.io/ls1intum/theia/java-17
image: ghcr.io/eduide/eduide/java-17
# imageTag: latest # Optional: override defaultImageTag for this app
requestsMemory: 2000M
requestsCpu: 500m
Expand All @@ -17,7 +17,7 @@ apps:
dataBridgePort: "16281"

- name: c-latest
image: ghcr.io/ls1intum/theia/c
image: ghcr.io/eduide/eduide/c
# imageTag: latest # Optional: override defaultImageTag for this app
requestsMemory: 100M
requestsCpu: 200m
Expand All @@ -29,7 +29,7 @@ apps:
dataBridgePort: "16281"

- name: javascript-latest
image: ghcr.io/ls1intum/theia/javascript
image: ghcr.io/eduide/eduide/javascript
# imageTag: latest # Optional: override defaultImageTag for this app
requestsMemory: 100M
requestsCpu: 200m
Expand All @@ -41,7 +41,7 @@ apps:
dataBridgePort: "16281"

- name: ocaml-latest
image: ghcr.io/ls1intum/theia/ocaml
image: ghcr.io/eduide/eduide/ocaml
# imageTag: latest # Optional: override defaultImageTag for this app
requestsMemory: 100M
requestsCpu: 200m
Expand All @@ -53,7 +53,7 @@ apps:
dataBridgePort: "16281"

- name: python-latest
image: ghcr.io/ls1intum/theia/python
image: ghcr.io/eduide/eduide/python
# imageTag: latest # Optional: override defaultImageTag for this app
requestsMemory: 100M
requestsCpu: 200m
Expand All @@ -65,7 +65,7 @@ apps:
dataBridgePort: "16281"

- name: rust-latest
image: ghcr.io/ls1intum/theia/rust
image: ghcr.io/eduide/eduide/rust
# imageTag: latest # Optional: override defaultImageTag for this app
requestsMemory: 100M
requestsCpu: 200m
Expand Down
2 changes: 1 addition & 1 deletion charts/theia-cloud-combined/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ appVersion: 1.0.0
dependencies:
- name: theia-cloud
version: 1.4.0-next.0
repository: "https://eduide.github.io/EduIDE-Helm"
repository: "oci://ghcr.io/eduide/charts"

- name: theia-certificates
version: 0.1.0
Expand Down
26 changes: 13 additions & 13 deletions charts/theia-cloud-combined/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,26 +41,26 @@ theia-cloud:
interval: 3

operator:
image: ghcr.io/ls1intum/theia/operator:latest
image: ghcr.io/eduide/eduide/operator:latest
replicas: 1
sessionsPerUser: 10
storageClassName: csi-rbd-sc
eagerStart: true

service:
image: ghcr.io/ls1intum/theia/service:latest
image: ghcr.io/eduide/eduide/service:latest
# Public token (must match app.id or be set explicitly)
authToken: nJV3nKZmpxTD4wu2

preloading:
images:
- ghcr.io/ls1intum/theia/landing-page:latest
- ghcr.io/ls1intum/theia/java-17:latest
- ghcr.io/ls1intum/theia/c:latest
- ghcr.io/ls1intum/theia/javascript:latest
- ghcr.io/ls1intum/theia/ocaml:latest
- ghcr.io/ls1intum/theia/rust:latest
- ghcr.io/ls1intum/theia/python:latest
- ghcr.io/eduide/eduide/landing-page:latest
- ghcr.io/eduide/eduide/java-17:latest
- ghcr.io/eduide/eduide/c:latest
- ghcr.io/eduide/eduide/javascript:latest
- ghcr.io/eduide/eduide/ocaml:latest
- ghcr.io/eduide/eduide/rust:latest
- ghcr.io/eduide/eduide/python:latest

imagePullPolicy: Always

Expand All @@ -70,7 +70,7 @@ theia-cloud:

landingPage:
# We use the try now page as landing page since the default does not support mutliple apps -> https://github.com/eclipsesource/theia-cloud/discussions/301
image: ghcr.io/ls1intum/theia/landing-page:latest
image: ghcr.io/eduide/eduide/landing-page:latest
# We can define a default blueprint
appDefinition: "java-17-latest"
ephemeralStorage: false
Expand Down Expand Up @@ -137,16 +137,16 @@ theia-appdefinitions:
# Individual apps can override the tag in their definition, e.g.:
# apps:
# - name: java-17-v1
# image: ghcr.io/ls1intum/theia/java-17
# image: ghcr.io/eduide/eduide/java-17
# imageTag: v1.0.0
# - name: python-v2
# image: ghcr.io/ls1intum/theia/python
# image: ghcr.io/eduide/eduide/python
# imageTag: v2.0.0

theia-workspace-garbage-collector:
replicaCount: 1
image:
repository: ghcr.io/ls1intum/theia/garbage-collector
repository: ghcr.io/eduide/eduide/garbage-collector
tag: latest
pullPolicy: Always

Expand Down
3 changes: 2 additions & 1 deletion charts/theia-shared-gateway/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ For production cluster values, use `deployments/shared-gateway-prod/values.yaml`

## Notes

- TLS secrets referenced by listeners must exist in `gateway.namespace`.
- The shared gateway chart should own the TLS material referenced by its listeners.
- For production, use cert-manager `Certificate` resources for concrete hosts and create the wildcard webview secret in `gateway.namespace` from the deploy-time wildcard certificate/key.
- Tenant charts should set:
- `theia-cloud.gateway.create=false`
- `theia-cloud.gateway.routes.enabled=true`
Expand Down
Loading