diff --git a/.github/workflows/deploy-pr.yml b/.github/workflows/deploy-pr.yml index bbabcd4..ef1afd6 100644 --- a/.github/workflows/deploy-pr.yml +++ b/.github/workflows/deploy-pr.yml @@ -48,7 +48,7 @@ on: clean_install: description: 'Clean Install: If true, perform namespace-scoped cleanup before install (delete sessions/workspaces, appdefinitions, deployments, daemonsets, statefulsets, PVCs).' required: false - default: false + default: true type: boolean jobs: diff --git a/.github/workflows/deploy-production.yml b/.github/workflows/deploy-production.yml index 0166829..187f303 100644 --- a/.github/workflows/deploy-production.yml +++ b/.github/workflows/deploy-production.yml @@ -47,6 +47,15 @@ on: 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 + clean_install: + description: 'Clean Install: If true, perform namespace-scoped cleanup before install (delete sessions/workspaces, appdefinitions, deployments, daemonsets, statefulsets, PVCs).' + required: false + default: false + type: boolean jobs: deploy: @@ -57,6 +66,7 @@ jobs: with: environment: theia-prod execution_mode: ${{ inputs.execution_mode || 'self-hosted-buildkit' }} + clean_install: ${{ github.event_name == 'workflow_dispatch' && (inputs.clean_install || false) }} deploy_shared_gateway: true shared_gateway_values_file: deployments/shared-gateway-prod/values.yaml shared_gateway_namespace: gateway-system diff --git a/.github/workflows/deploy-staging.yml b/.github/workflows/deploy-staging.yml index 2a6d9cc..657c3d2 100644 --- a/.github/workflows/deploy-staging.yml +++ b/.github/workflows/deploy-staging.yml @@ -38,6 +38,15 @@ on: 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 + clean_install: + description: 'Clean Install: If true, perform namespace-scoped cleanup before install (delete sessions/workspaces, appdefinitions, deployments, daemonsets, statefulsets, PVCs).' + required: false + default: false + type: boolean jobs: deploy: @@ -48,6 +57,7 @@ jobs: with: environment: theia-staging execution_mode: ${{ inputs.execution_mode || 'self-hosted-buildkit' }} + clean_install: ${{ github.event_name == 'workflow_dispatch' && (inputs.clean_install || false) }} deploy_shared_gateway: true shared_gateway_values_file: deployments/shared-gateway/values.yaml shared_gateway_namespace: gateway-system diff --git a/README.md b/README.md index 01b25e9..8339aef 100644 --- a/README.md +++ b/README.md @@ -176,9 +176,26 @@ The recommended approach is to use the automated GitHub Actions workflows: See [Deployment Workflows](docs/deployment-workflows.md) for detailed instructions. +### Updating pinned release tags + +Staging and production intentionally pin several images to SHA-suffixed tags such as `latest-dfe0d09`, `latest-2c6f8ac`, and `latest-0c8eec9`. + +When a new release is published, you must update the short SHA suffix in the environment values files instead of relying on plain `latest`. In practice this means bumping: + +- `theia-cloud.operator.image` +- `theia-cloud.service.image` +- `theia-cloud.preloading.images` +- `theia-cloud.landingPage.image` +- `conversion.image` in `theia-crds-helm-values.yml` + +The landing page can use a different SHA suffix from the IDE images, so keep `theia-cloud.landingPage.image` and `theia-cloud.preloading.images[0]` aligned with each other, and keep the remaining IDE preload tags aligned separately. + +See [Deployment Workflows](docs/deployment-workflows.md#release-process-for-pinned-image-tags) for the full release checklist. + ## Common Tasks - **Deploy a PR to test environment**: See [Deployment Workflows](docs/deployment-workflows.md#pull-request-deployments) +- **Bump release image tags**: See [Deployment Workflows](docs/deployment-workflows.md#release-process-for-pinned-image-tags) - **Add a new environment**: See [Adding Environments](docs/adding-environments.md) - **Configure Keycloak authentication**: See [Keycloak Setup](docs/keycloak-setup.md) - **Request TUM wildcard certificates**: See [TUM Certificates](docs/tum-certificates.md) diff --git a/deployments/test1.theia-test.artemis.cit.tum.de/theia-crds-helm-values.yml b/deployments/test1.theia-test.artemis.cit.tum.de/theia-crds-helm-values.yml index 3a28892..abfb30a 100644 --- a/deployments/test1.theia-test.artemis.cit.tum.de/theia-crds-helm-values.yml +++ b/deployments/test1.theia-test.artemis.cit.tum.de/theia-crds-helm-values.yml @@ -2,4 +2,4 @@ clusterIssuer: theia-cloud-selfsigned-issuer conversion: - image: ghcr.io/eduide/eduide-cloud/conversion-webhook:pr-70 + image: ghcr.io/eduide/eduide-cloud/conversion-webhook:latest diff --git a/deployments/test2.theia-test.artemis.cit.tum.de/theia-crds-helm-values.yml b/deployments/test2.theia-test.artemis.cit.tum.de/theia-crds-helm-values.yml index 3a28892..abfb30a 100644 --- a/deployments/test2.theia-test.artemis.cit.tum.de/theia-crds-helm-values.yml +++ b/deployments/test2.theia-test.artemis.cit.tum.de/theia-crds-helm-values.yml @@ -2,4 +2,4 @@ clusterIssuer: theia-cloud-selfsigned-issuer conversion: - image: ghcr.io/eduide/eduide-cloud/conversion-webhook:pr-70 + image: ghcr.io/eduide/eduide-cloud/conversion-webhook:latest diff --git a/deployments/test3.theia-test.artemis.cit.tum.de/theia-crds-helm-values.yml b/deployments/test3.theia-test.artemis.cit.tum.de/theia-crds-helm-values.yml index 429a98e..74acd42 100644 --- a/deployments/test3.theia-test.artemis.cit.tum.de/theia-crds-helm-values.yml +++ b/deployments/test3.theia-test.artemis.cit.tum.de/theia-crds-helm-values.yml @@ -2,4 +2,4 @@ clusterIssuer: theia-cloud-selfsigned-issuer conversion: - image: ghcr.io/eduide/eduide-cloud/conversion-webhook:pr-70 + image: ghcr.io/eduide/eduide-cloud/conversion-webhook:latest diff --git a/deployments/theia-staging.artemis.cit.tum.de/theia-crds-helm-values.yml b/deployments/theia-staging.artemis.cit.tum.de/theia-crds-helm-values.yml index 3a28892..d6dc778 100644 --- a/deployments/theia-staging.artemis.cit.tum.de/theia-crds-helm-values.yml +++ b/deployments/theia-staging.artemis.cit.tum.de/theia-crds-helm-values.yml @@ -2,4 +2,4 @@ clusterIssuer: theia-cloud-selfsigned-issuer conversion: - image: ghcr.io/eduide/eduide-cloud/conversion-webhook:pr-70 + image: ghcr.io/eduide/eduide-cloud/conversion-webhook:latest-dfe0d09 diff --git a/deployments/theia-staging.artemis.cit.tum.de/values.yaml b/deployments/theia-staging.artemis.cit.tum.de/values.yaml index c5f61ce..308950d 100644 --- a/deployments/theia-staging.artemis.cit.tum.de/values.yaml +++ b/deployments/theia-staging.artemis.cit.tum.de/values.yaml @@ -42,33 +42,33 @@ theia-cloud: interval: 3 operator: - #image: ghcr.io/eduide/eduide-cloud/operator:latest + image: ghcr.io/eduide/eduide-cloud/operator:latest-dfe0d09 #eagerStart: false replicas: 1 sessionsPerUser: 10 storageClassName: csi-rbd-sc - # service: - # image: ghcr.io/eduide/eduide-cloud/service:latest - # adminApiTokenSecret: - # name: service-admin-api-token - # key: ADMIN_API_TOKEN + service: + image: ghcr.io/eduide/eduide-cloud/service:latest-dfe0d09 + adminApiTokenSecret: + name: service-admin-api-token + key: ADMIN_API_TOKEN # Preload list indices 0–10 must match deploy-theia.yml --set overrides when tags are passed. # Index 11 is oauth2-proxy (distroless); the workflow does not override it. preloading: images: - - ghcr.io/eduide/eduidec-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 - - ghcr.io/eduide/eduide/java-17-no-ls:latest - - ghcr.io/eduide/eduide/rust-no-ls:latest - - ghcr.io/eduide/eduide/langserver-java:latest - - ghcr.io/eduide/eduide/langserver-rust:latest + - ghcr.io/eduide/eduidec-landing-page:latest-2c6f8ac + - ghcr.io/eduide/eduide/java-17:latest-0c8eec9 + - ghcr.io/eduide/eduide/c:latest-0c8eec9 + - ghcr.io/eduide/eduide/javascript:latest-0c8eec9 + - ghcr.io/eduide/eduide/ocaml:latest-0c8eec9 + - ghcr.io/eduide/eduide/rust:latest-0c8eec9 + - ghcr.io/eduide/eduide/python:latest-0c8eec9 + - ghcr.io/eduide/eduide/java-17-no-ls:latest-0c8eec9 + - ghcr.io/eduide/eduide/rust-no-ls:latest-0c8eec9 + - ghcr.io/eduide/eduide/langserver-java:latest-0c8eec9 + - ghcr.io/eduide/eduide/langserver-rust:latest-0c8eec9 - image: quay.io/oauth2-proxy/oauth2-proxy:v7.12.0 args: ["--version"] @@ -80,7 +80,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/eduidec-landing-page + image: ghcr.io/eduide/eduidec-landing-page:latest-2c6f8ac logoFileExtension: "png" # We can define a default blueprint appDefinition: "java-17-latest" diff --git a/deployments/theia.artemis.cit.tum.de/theia-crds-helm-values.yml b/deployments/theia.artemis.cit.tum.de/theia-crds-helm-values.yml index 3a28892..d6dc778 100644 --- a/deployments/theia.artemis.cit.tum.de/theia-crds-helm-values.yml +++ b/deployments/theia.artemis.cit.tum.de/theia-crds-helm-values.yml @@ -2,4 +2,4 @@ clusterIssuer: theia-cloud-selfsigned-issuer conversion: - image: ghcr.io/eduide/eduide-cloud/conversion-webhook:pr-70 + image: ghcr.io/eduide/eduide-cloud/conversion-webhook:latest-dfe0d09 diff --git a/deployments/theia.artemis.cit.tum.de/values.yaml b/deployments/theia.artemis.cit.tum.de/values.yaml index d3f8fa5..fe364eb 100644 --- a/deployments/theia.artemis.cit.tum.de/values.yaml +++ b/deployments/theia.artemis.cit.tum.de/values.yaml @@ -42,33 +42,33 @@ theia-cloud: interval: 3 operator: - #image: ghcr.io/eduide/eduide-cloud/operator:latest + image: ghcr.io/eduide/eduide-cloud/operator:latest-dfe0d09 #eagerStart: false replicas: 3 sessionsPerUser: 10 storageClassName: csi-rbd-sc - # service: - # image: ghcr.io/eduide/eduide-cloud/service:latest - # adminApiTokenSecret: - # name: service-admin-api-token - # key: ADMIN_API_TOKEN + service: + image: ghcr.io/eduide/eduide-cloud/service:latest-dfe0d09 + adminApiTokenSecret: + name: service-admin-api-token + key: ADMIN_API_TOKEN # Preload list indices 0–10 must match deploy-theia.yml --set overrides when tags are passed. # Index 11 is oauth2-proxy (distroless); the workflow does not override it. preloading: images: - - ghcr.io/eduide/eduidec-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 - - ghcr.io/eduide/eduide/java-17-no-ls:latest - - ghcr.io/eduide/eduide/rust-no-ls:latest - - ghcr.io/eduide/eduide/langserver-java:latest - - ghcr.io/eduide/eduide/langserver-rust:latest + - ghcr.io/eduide/eduidec-landing-page:latest-2c6f8ac + - ghcr.io/eduide/eduide/java-17:latest-0c8eec9 + - ghcr.io/eduide/eduide/c:latest-0c8eec9 + - ghcr.io/eduide/eduide/javascript:latest-0c8eec9 + - ghcr.io/eduide/eduide/ocaml:latest-0c8eec9 + - ghcr.io/eduide/eduide/rust:latest-0c8eec9 + - ghcr.io/eduide/eduide/python:latest-0c8eec9 + - ghcr.io/eduide/eduide/java-17-no-ls:latest-0c8eec9 + - ghcr.io/eduide/eduide/rust-no-ls:latest-0c8eec9 + - ghcr.io/eduide/eduide/langserver-java:latest-0c8eec9 + - ghcr.io/eduide/eduide/langserver-rust:latest-0c8eec9 - image: quay.io/oauth2-proxy/oauth2-proxy:v7.12.0 args: ["--version"] @@ -80,7 +80,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/eduidec-landing-page + image: ghcr.io/eduide/eduidec-landing-page:latest-2c6f8ac logoFileExtension: "png" # We can define a default blueprint appDefinition: "java-17-latest" diff --git a/docs/deployment-workflows.md b/docs/deployment-workflows.md new file mode 100644 index 0000000..30d7cfd --- /dev/null +++ b/docs/deployment-workflows.md @@ -0,0 +1,133 @@ +# Deployment Workflows + +This repository deploys Theia Cloud through three GitHub Actions entrypoints that all call the reusable [`deploy-theia.yml`](../.github/workflows/deploy-theia.yml) workflow. + +## Workflow Overview + +### Pull request deployments + +- Workflow: [`deploy-pr.yml`](../.github/workflows/deploy-pr.yml) +- Trigger: pull requests (`opened`, `synchronize`, `reopened`) and manual `workflow_dispatch` +- Targets: `test1`, `test2`, `test3` +- Manual inputs: + - `theia_cloud_tag` + - `landing_page_tag` + - `ide_images_tag` + - `execution_mode` + - `helm_chart_tag` + - `clean_install` + +`clean_install` now defaults to `true` for manual PR deployments. + +### Staging deployments + +- Workflow: [`deploy-staging.yml`](../.github/workflows/deploy-staging.yml) +- Trigger: push to `main` and manual `workflow_dispatch` +- Target: `theia-staging` +- Manual inputs: + - `execution_mode` + - `clean_install` + +### Production deployments + +- Workflow: [`deploy-production.yml`](../.github/workflows/deploy-production.yml) +- Trigger: manual `workflow_dispatch` +- Target: `theia-prod` +- Manual inputs: + - `execution_mode` + - `clean_install` + +## Manual Deployment Inputs + +### `execution_mode` + +Selects which runner backend executes the deployment: + +- `self-hosted-buildkit` +- `github-runners` + +### `clean_install` + +When enabled, the reusable deployment workflow performs a namespace-scoped cleanup before Helm install: + +- deletes session and workspace resources +- deletes AppDefinitions +- deletes deployments, daemonsets, and statefulsets +- waits for pods to terminate +- deletes PVCs + +Use this when you need a clean rollout and are prepared to remove the namespace-local runtime state. + +## Release Process For Pinned Image Tags + +Staging and production now intentionally pin several images to SHA-suffixed tags instead of floating on plain `latest`. A release therefore requires updating the short SHA suffix in the deployment values files. + +### Which files to update + +For staging: + +- [`deployments/theia-staging.artemis.cit.tum.de/values.yaml`](../deployments/theia-staging.artemis.cit.tum.de/values.yaml) +- [`deployments/theia-staging.artemis.cit.tum.de/theia-crds-helm-values.yml`](../deployments/theia-staging.artemis.cit.tum.de/theia-crds-helm-values.yml) + +For production: + +- [`deployments/theia.artemis.cit.tum.de/values.yaml`](../deployments/theia.artemis.cit.tum.de/values.yaml) +- [`deployments/theia.artemis.cit.tum.de/theia-crds-helm-values.yml`](../deployments/theia.artemis.cit.tum.de/theia-crds-helm-values.yml) + +### Tags that currently need to be bumped together + +In each environment `values.yaml`: + +- `theia-cloud.operator.image` +- `theia-cloud.service.image` +- `theia-cloud.preloading.images[0..10]` +- `theia-cloud.landingPage.image` + +In each environment `theia-crds-helm-values.yml`: + +- `conversion.image` + +### Practical rule + +There are currently three image families with separate tag suffixes: + +- Theia Cloud control-plane images: + - `operator` + - `service` + - `conversion-webhook` +- Landing page images: + - `theia-cloud.landingPage.image` + - `theia-cloud.preloading.images[0]` +- IDE and language-server images: + - `theia-cloud.preloading.images[1..10]` + +If a new release publishes a new short SHA for one of those families, update every field in that family in both staging and production before merging. + +### Recommended release checklist + +1. Confirm the published image tags in GHCR. +2. Update staging and production values files with the new short SHA suffixes. +3. Keep `theia-cloud.landingPage.image` and `theia-cloud.preloading.images[0]` in sync. +4. Keep `theia-cloud.preloading.images[1..10]` aligned with the intended IDE and language-server release. +5. Keep `operator`, `service`, and `conversion.image` in sync when rolling a new control-plane build. +6. If test environments should stop using a PR-specific conversion webhook, update their `theia-crds-helm-values.yml` files as well. +7. Validate the edited YAML files before opening the PR. + +Example validation: + +```bash +ruby -e 'require "yaml"; %w[ + .github/workflows/deploy-pr.yml + .github/workflows/deploy-staging.yml + .github/workflows/deploy-production.yml + deployments/theia-staging.artemis.cit.tum.de/values.yaml + deployments/theia-staging.artemis.cit.tum.de/theia-crds-helm-values.yml + deployments/theia.artemis.cit.tum.de/values.yaml + deployments/theia.artemis.cit.tum.de/theia-crds-helm-values.yml +].each { |f| YAML.load_file(f); puts "OK #{f}" }' +``` + +## Notes + +- PR workflows can temporarily override image tags with workflow inputs, so you do not need to edit committed values files for preview deployments. +- Staging and production use committed values files as the source of truth, so release tag bumps must happen in git.