Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a56f738
Migrate test3 to AppDefinition v1beta11 sidecars on clean main-based …
CodeByNikolas Mar 16, 2026
ddd6a0e
ci: bump theia-cloud-crds base version to 1.2.0-next.1
CodeByNikolas Mar 16, 2026
36e2400
ci(test3): override conversion-webhook image to PR build
CodeByNikolas Mar 16, 2026
20d3c61
chore(test3): remove stale pr-46 preloading images
CodeByNikolas Mar 16, 2026
d316777
fix: correct garbage-collector image path to ghcr.io/eduide/garbage-c…
CodeByNikolas Mar 16, 2026
edd722b
Merge branch 'main' into feat/test3-pr70-sidecar-clean
CodeByNikolas Mar 16, 2026
6e19887
fix(test3): align sidecar appdefinitions with reviewer findings
CodeByNikolas Mar 16, 2026
6665fb5
fix(test3): switch no-ls and langserver images to eduide registry
CodeByNikolas Mar 16, 2026
606c591
ci(deploy): tag no-ls and sidecar preloading images with ide_images_tag
CodeByNikolas Mar 16, 2026
6244c38
add conversion images
CodeByNikolas Mar 17, 2026
5d1f00c
conversion webhook
CodeByNikolas Mar 17, 2026
47b5b91
fix(test3): switch operator storageClassName to longhorn for RWX support
CodeByNikolas Mar 17, 2026
f8b91b3
fix(ci): empty tag inputs no longer override values.yaml image settin…
CodeByNikolas Mar 17, 2026
f5205db
fix(ci): empty tag inputs no longer override values.yaml image settings
CodeByNikolas Mar 17, 2026
db17c2b
feat: add 'all' option to workflow_dispatch environment input
CodeByNikolas Mar 17, 2026
5a25db3
fix(test3): use valid operator image path for pr-70 deployments
CodeByNikolas Mar 17, 2026
06092d8
fix(ci): remove environment selector from manual dispatch, always run…
CodeByNikolas Mar 17, 2026
6fbb7fc
Merge remote-tracking branch 'origin/fix/empty-tag-no-override-main-o…
CodeByNikolas Mar 17, 2026
de71aed
update values
CodeByNikolas Mar 17, 2026
29a07ad
fix(test3): pin no-ls and sidecar images to pr-124
CodeByNikolas Mar 17, 2026
2593382
fix(rbac): allow operator to delete sidecar pod collections
CodeByNikolas Mar 17, 2026
a678395
Potential fix for pull request finding
CodeByNikolas Mar 19, 2026
68dd3a6
fix(pr73): v1beta10 lookup fallback, test3 tag alignment, deploy prel…
CodeByNikolas Mar 19, 2026
f393360
feat(ci): add execution_mode dropdown + runner routing, revert v1beta…
CodeByNikolas Mar 19, 2026
60cf941
merge main into PR #73 and keep execution mode + strict migration cho…
CodeByNikolas Mar 19, 2026
49faaef
ci: add runner debug step and adopt sidecar RBAC into Helm
CodeByNikolas Mar 19, 2026
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
11 changes: 11 additions & 0 deletions .github/workflows/deploy-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ on:
description: 'IDE images tag (appdefinitions and preloading). Leave empty to use the tag defined in values.yaml (no override).'
required: false
default: ''
execution_mode:
description: 'Runner backend to use (self-hosted-buildkit or github-runners)'
required: false
default: 'self-hosted-buildkit'
type: choice
options:
- self-hosted-buildkit
- github-runners
helm_chart_tag:
description: 'Preview OCI tag from theia-cloud-helm to use (for example pr-123)'
required: false
Expand All @@ -47,6 +55,7 @@ jobs:
environment: test1
theia_cloud_tag: ${{ inputs.theia_cloud_tag }}
ide_images_tag: ${{ inputs.ide_images_tag }}
execution_mode: ${{ inputs.execution_mode || 'self-hosted-buildkit' }}
helm_chart_tag: ${{ inputs.helm_chart_tag || '' }}
deploy_shared_gateway: false
shared_gateway_values_file: deployments/shared-gateway/values.yaml
Expand All @@ -65,6 +74,7 @@ jobs:
environment: test2
theia_cloud_tag: ${{ inputs.theia_cloud_tag }}
ide_images_tag: ${{ inputs.ide_images_tag }}
execution_mode: ${{ inputs.execution_mode || 'self-hosted-buildkit' }}
helm_chart_tag: ${{ inputs.helm_chart_tag || '' }}
deploy_shared_gateway: false
shared_gateway_values_file: deployments/shared-gateway/values.yaml
Expand All @@ -83,6 +93,7 @@ jobs:
environment: test3
theia_cloud_tag: ${{ inputs.theia_cloud_tag }}
ide_images_tag: ${{ inputs.ide_images_tag }}
execution_mode: ${{ inputs.execution_mode || 'self-hosted-buildkit' }}
helm_chart_tag: ${{ inputs.helm_chart_tag || '' }}
deploy_shared_gateway: false
shared_gateway_values_file: deployments/shared-gateway/values.yaml
Expand Down
31 changes: 29 additions & 2 deletions .github/workflows/deploy-theia.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,37 @@ on:
required: false
type: string
default: "gateway-system"
execution_mode:
description: "Runner backend to use (self-hosted-buildkit or github-runners)"
required: false
type: string
default: "self-hosted-buildkit"

jobs:
helm-install:
name: Install Theia Cloud Helm Chart
permissions:
contents: read
packages: read
runs-on: ubuntu-latest
runs-on: ${{ inputs.execution_mode == 'github-runners' && 'ubuntu-latest' || 'arc-buildkit-eduide-amd64' }}
# Link to GitHub Environment for secrets and protection rules
environment: ${{ inputs.environment }}

steps:
- name: Debug runner and execution context
run: |
set -euo pipefail
echo "execution_mode input: ${{ inputs.execution_mode }}"
echo "runner.name: ${{ runner.name }}"
echo "runner.os: ${{ runner.os }}"
echo "runner.arch: ${{ runner.arch }}"
echo "github.job: ${{ github.job }}"
echo "hostname: $(hostname)"
echo "kernel: $(uname -a)"
echo "whoami: $(whoami)"
echo "kubectl version (client):"
kubectl version --client || true

# Step 1: Checkout the repository to access Helm charts and values
- name: Checkout repository
uses: actions/checkout@v4
Expand Down Expand Up @@ -162,7 +181,7 @@ jobs:
set -euo pipefail

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

if [ -n "${{ inputs.helm_chart_tag }}" ]; then
normalize_preview_version() {
Expand Down Expand Up @@ -221,6 +240,13 @@ jobs:
run: |
set -euo pipefail

# Adopt pre-existing RBAC objects into this Helm release if they already exist.
# This avoids "resource exists and cannot be imported" errors during upgrade.
kubectl -n "${{ vars.NAMESPACE }}" annotate role/operator-sidecar-pod-restart meta.helm.sh/release-name=theia-cloud-combined meta.helm.sh/release-namespace="${{ vars.NAMESPACE }}" --overwrite >/dev/null 2>&1 || true
kubectl -n "${{ vars.NAMESPACE }}" label role/operator-sidecar-pod-restart app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
kubectl -n "${{ vars.NAMESPACE }}" annotate rolebinding/operator-sidecar-pod-restart meta.helm.sh/release-name=theia-cloud-combined meta.helm.sh/release-namespace="${{ vars.NAMESPACE }}" --overwrite >/dev/null 2>&1 || true
kubectl -n "${{ vars.NAMESPACE }}" label rolebinding/operator-sidecar-pod-restart app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true

# Prepare SSL certificates for ingress
# Note: Secrets are already base64 encoded, but we need to write them to files
echo "${{ secrets.THEIA_WILDCARD_CERTIFICATE_CERT }}" | base64 -w 0 > wildcard.crt
Expand Down Expand Up @@ -260,6 +286,7 @@ jobs:
--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}"
# Intentionally override no-ls + langserver preload images globally when IDE tag is overridden.
--set "theia-cloud.preloading.images[7]=ghcr.io/eduide/eduide/java-17-no-ls:${IDE_IMAGES_TAG}"
--set "theia-cloud.preloading.images[8]=ghcr.io/eduide/eduide/rust-no-ls:${IDE_IMAGES_TAG}"
--set "theia-cloud.preloading.images[9]=ghcr.io/eduide/eduide/langserver-java:${IDE_IMAGES_TAG}"
Expand Down
40 changes: 38 additions & 2 deletions charts/theia-appdefinitions/templates/appdefinition.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{{- range .Values.apps }}
{{- $existingApp := lookup "theia.cloud/v1beta10" "AppDefinition" $.Release.Namespace .name }}
{{- $existingApp := lookup "theia.cloud/v1beta11" "AppDefinition" $.Release.Namespace .name }}
{{- $existingSpec := dict }}
{{- if $existingApp }}
{{- $existingSpec = get $existingApp "spec" | default dict }}
Expand All @@ -14,7 +14,7 @@
{{- $maxInstances = get $existingSpec "maxInstances" }}
{{- end }}
---
apiVersion: theia.cloud/v1beta10
apiVersion: theia.cloud/v1beta11
kind: AppDefinition
metadata:
name: {{ .name }}
Expand Down Expand Up @@ -54,4 +54,40 @@ spec:
options:
{{- toYaml .options | nindent 4 }}
{{- end }}
{{- if .sidecars }}
sidecars:
{{- range .sidecars }}
- name: {{ .name }}
{{- $sidecarImage := .image }}
{{- if or (contains "@sha256:" $sidecarImage) (regexMatch ".*:[^/]+$" $sidecarImage) }}
image: {{ $sidecarImage }}
{{- else }}
image: {{ $sidecarImage }}:{{ .imageTag | default $.Values.defaultImageTag | default "latest" }}
{{- end }}
port: {{ .port | default 5000 }}
{{- if .languages }}
languages:
{{- range .languages }}
- {{ . }}
{{- end }}
{{- end }}
{{- if .cpuLimit }}
cpuLimit: {{ .cpuLimit }}
{{- end }}
{{- if .memoryLimit }}
memoryLimit: {{ .memoryLimit }}
{{- end }}
{{- if .cpuRequest }}
cpuRequest: {{ .cpuRequest }}
{{- end }}
{{- if .memoryRequest }}
memoryRequest: {{ .memoryRequest }}
{{- end }}
{{- if hasKey . "mountWorkspace" }}
mountWorkspace: {{ .mountWorkspace }}
{{- else }}
mountWorkspace: true
{{- end }}
{{- end }}
{{- end }}
{{- end }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: operator-sidecar-pod-restart
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/managed-by: Helm
rules:
- apiGroups: [""]
resources: ["pods"]
# deletecollection is intentionally kept for batch sidecar-pod restart cleanup operations.
verbs: ["get", "list", "watch", "delete", "deletecollection"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: operator-sidecar-pod-restart
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/managed-by: Helm
subjects:
- kind: ServiceAccount
name: operator-api-service-account
namespace: {{ .Release.Namespace }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: operator-sidecar-pod-restart
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# -- The cluster issuer to use for the certificate
clusterIssuer: theia-cloud-selfsigned-issuer

conversion:
image: ghcr.io/eduide/eduide-cloud/conversion-webhook:pr-70
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# -- The cluster issuer to use for the certificate
clusterIssuer: theia-cloud-selfsigned-issuer

conversion:
image: ghcr.io/eduide/eduide-cloud/conversion-webhook:pr-70
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# -- The cluster issuer to use for the certificate
# Name of the cert-manager ClusterIssuer used to issue TLS certificates for this deployment.
clusterIssuer: theia-cloud-selfsigned-issuer

conversion:
image: ghcr.io/eduide/eduide-cloud/conversion-webhook:pr-70
71 changes: 39 additions & 32 deletions deployments/test3.theia-test.artemis.cit.tum.de/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,34 +43,37 @@ theia-cloud:
interval: 3

operator:
image: ghcr.io/eduide/eduide/operator:latest
image: ghcr.io/eduide/eduide-cloud/operator:pr-70
#eagerStart: false
replicas: 1
sessionsPerUser: 10
storageClassName: csi-rbd-sc
# Test3 runs on the parma cluster where Longhorn is the default storage backend.
storageClassName: longhorn
resources:
requests:
ephemeral-storage: "128Mi"
limits:
ephemeral-storage: "256Mi"

# service:
# image: ghcr.io/eduide/eduide/service:latest
# adminApiTokenSecret:
# name: service-admin-api-token
# key: ADMIN_API_TOKEN
service:
image: ghcr.io/eduide/eduide-cloud/service:pr-70
adminApiTokenSecret:
name: service-admin-api-token
key: ADMIN_API_TOKEN

preloading:
images:
- ghcr.io/eduide/eduide/landing-page:latest
- ghcr.io/eduide/eduide-cloud/landing-page:pr-70
- 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
- ghcr.io/eduide/eduide/theia-no-ls:pr-46
- ghcr.io/eduide/eduide/langserver-java:pr-46
- ghcr.io/eduide/eduide/java-17-no-ls:pr-70
- ghcr.io/eduide/eduide/rust-no-ls:pr-70
- ghcr.io/eduide/eduide/langserver-java:pr-70
- ghcr.io/eduide/eduide/langserver-rust:pr-70

imagePullPolicy: Always

Expand All @@ -80,7 +83,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/eduide/eduide/landing-page
image: ghcr.io/eduide/eduide-cloud/landing-page:pr-70
# We can define a default blueprint

# 1. The actual image data (Must be a Base64 encoded string)
Expand All @@ -90,25 +93,15 @@ theia-cloud:
# 2. (Optional) If you removed the 'hardcoded png' logic in the template,
# you might need this. If you used my simplified template, this is ignored.
logoFileExtension: "png"
appDefinition: "java-17-latest"
appDefinition: "java-17-no-ls"
ephemeralStorage: true
additionalApps:
java-17-latest:
label: Java 17
c-latest:
label: C
javascript-latest:
label: Javascript
ocaml-latest:
label: Ocaml
python-latest:
label: Python
rust-latest:
label: Rust
java-ls-test:
label: Java LS Test
java-17-no-ls:
label: Java 17 No-LS (Sidecar)
rust-no-ls:
label: Rust No-LS (Sidecar)
infoTitle: "🚀 Welcome to Test3 IDE Environment"
infoText: "This is a testing environment for Theia Cloud. Select your programming language and start coding in seconds!"
infoText: "Test environment for Theia with external language server architecture (PR #70). The IDE runs separately from the language server for improved performance and modularity."
loadingText: "⚡ Setting up your development workspace..."
footerLinks:
attribution:
Expand Down Expand Up @@ -138,12 +131,26 @@ theia-cloud:
clientId: "theia-test"

theia-appdefinitions:
defaultImageTag: pr-70
apps:
- name: java-ls-test
image: ghcr.io/eduide/eduide/theia-no-ls
imageTag: pr-46
options:
langserver-image: ghcr.io/eduide/eduide/langserver-java:pr-46
- name: java-17-no-ls
image: ghcr.io/eduide/eduide/java-17-no-ls
minInstances: 1
sidecars:
- name: langserver
image: ghcr.io/eduide/eduide/langserver-java
port: 5000
languages: [java]
mountWorkspace: true
- name: rust-no-ls
image: ghcr.io/eduide/eduide/rust-no-ls
minInstances: 1
sidecars:
- name: langserver
image: ghcr.io/eduide/eduide/langserver-rust
port: 5000
languages: [rust]
mountWorkspace: true

monitoring:
targetNamespaces:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# -- The cluster issuer to use for the certificate
clusterIssuer: theia-cloud-selfsigned-issuer

conversion:
image: ghcr.io/eduide/eduide-cloud/conversion-webhook:pr-70
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# -- The cluster issuer to use for the certificate
clusterIssuer: theia-cloud-selfsigned-issuer
clusterIssuer: theia-cloud-selfsigned-issuer

conversion:
image: ghcr.io/eduide/eduide-cloud/conversion-webhook:pr-70
22 changes: 4 additions & 18 deletions docs/adding-environments.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,31 +172,17 @@ dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64 | tr -d -- '\n' | tr -- '+

Edit [.github/workflows/deploy-pr.yml](../.github/workflows/deploy-pr.yml):

1. Add the environment to the `options` list:

```yaml
workflow_dispatch:
inputs:
environment:
description: 'Target Environment'
required: true
type: choice
options:
- test1
- test2 # Add your new environment
```

2. Add a new job for the environment:
1. Add a new job for the environment (manual dispatch now deploys to all jobs; there is no `environment` selector input):

```yaml
deploy-test2:
if: github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && inputs.environment == 'test2')
if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
name: Deploy to Test2
uses: ./.github/workflows/deploy-theia.yml
with:
environment: test2
theia_cloud_tag: ${{ inputs.theia_cloud_tag || 'latest' }}
ide_images_tag: ${{ inputs.ide_images_tag || 'latest' }}
theia_cloud_tag: ${{ inputs.theia_cloud_tag }}
ide_images_tag: ${{ inputs.ide_images_tag }}
helm_chart_tag: ${{ inputs.helm_chart_tag || '' }}
deploy_shared_gateway: true
shared_gateway_values_file: deployments/shared-gateway/values.yaml
Expand Down
Loading