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
50 changes: 24 additions & 26 deletions .github/workflows/deploy-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
# PR Deployment Workflow
# ==============================================================================
# This workflow handles deployments triggered by pull requests and manual
# selections via the GitHub Actions UI.
# dispatch via the GitHub Actions UI.
#
# Manual dispatch (workflow_dispatch) always triggers all three environment
# jobs (test1, test2, test3). Each job is still gated by its own GitHub
# Environment approval before the actual deployment runs.
# ==============================================================================

name: Deploy PR to Environment
Expand All @@ -12,81 +16,75 @@
pull_request:
types: [opened, synchronize, reopened]

# Manual trigger via GitHub UI
# Manual trigger via GitHub UI – always deploys to all three environments.
# Per-environment approvals (configured in GitHub Environment settings) still
# gate each individual job before deployment proceeds.
workflow_dispatch:
inputs:
environment:
description: "Select environment to deploy to"
required: true
type: choice
options:
- test1
- test2
- test3
theia_cloud_tag:
description: 'Theia Cloud components tag (operator, service, landing-page)'
description: 'Theia Cloud components tag (operator, service, landing-page). Leave empty to use the tag defined in values.yaml (no override).'
required: false
default: 'latest'
default: ''
ide_images_tag:
description: 'IDE images tag (appdefinitions and preloading)'
description: 'IDE images tag (appdefinitions and preloading). Leave empty to use the tag defined in values.yaml (no override).'
required: false
default: 'latest'
default: ''
helm_chart_tag:
description: 'Preview OCI tag from theia-cloud-helm to use (for example pr-123)'
required: false
default: ''

jobs:
# Job 1: Deploy to Test1 environment
# Runs automatically on all PR events OR when manually selected
# Runs automatically on all PR events OR on any manual dispatch.
# Environment variables NAMESPACE and HELM_VALUES_PATH are read from GitHub Environment settings.
# Shared gateway inputs are hardcoded in each job below.
deploy-test1:
if: github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && inputs.environment == 'test1')
if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
name: Deploy to Test1
uses: ./.github/workflows/deploy-theia.yml
with:
environment: test1
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: false
shared_gateway_values_file: deployments/shared-gateway/values.yaml
shared_gateway_namespace: gateway-system
secrets: inherit

# Job 2: Deploy to Test2 environment
# Runs automatically on all PR events OR when manually selected
# Runs automatically on all PR events OR on any manual dispatch.
# Environment variables NAMESPACE and HELM_VALUES_PATH are read from GitHub Environment settings.
# Shared gateway inputs are hardcoded in each job below.
deploy-test2:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {}
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: false
shared_gateway_values_file: deployments/shared-gateway/values.yaml
shared_gateway_namespace: gateway-system
secrets: inherit

# Job 3: Deploy to Test3 environment
# Runs automatically on all PR events OR when manually selected
# Runs automatically on all PR events OR on any manual dispatch.
# Environment variables NAMESPACE and HELM_VALUES_PATH are read from GitHub Environment settings.
# Shared gateway inputs are hardcoded in each job below.
deploy-test3:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {}
if: github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && inputs.environment == 'test3')
if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
name: Deploy to Test3
uses: ./.github/workflows/deploy-theia.yml
with:
environment: test3
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: false
shared_gateway_values_file: deployments/shared-gateway/values.yaml
shared_gateway_namespace: gateway-system
secrets: inherit

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {}
69 changes: 45 additions & 24 deletions .github/workflows/deploy-theia.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ on:
required: true
type: string
theia_cloud_tag:
description: "Image tag for Theia Cloud components (operator, service, landing-page)"
description: "Image tag for Theia Cloud components (operator, service, landing-page). Leave empty to use the tag defined in values.yaml (no override)."
required: false
type: string
default: "latest"
default: ""
ide_images_tag:
description: "Image tag for IDE images (appdefinitions and preloading)"
description: "Image tag for IDE images (appdefinitions and preloading). Leave empty to use the tag defined in values.yaml (no override)."
required: false
type: string
default: "latest"
default: ""
helm_chart_tag:
description: "Published OCI preview tag to use for upstream helm charts (e.g. pr-123)"
required: false
Expand Down Expand Up @@ -219,6 +219,8 @@ jobs:
env:
KUBECONFIG: ${{ github.workspace }}/kubeconfig
run: |
set -euo pipefail

# 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 All @@ -229,26 +231,45 @@ jobs:
THEIA_CLOUD_TAG="${{ inputs.theia_cloud_tag }}"
IDE_IMAGES_TAG="${{ inputs.ide_images_tag }}"

# Build base helm command with always-present flags
HELM_CMD=(helm upgrade --install theia-cloud-combined ./charts/theia-cloud-combined
--namespace ${{ vars.NAMESPACE }}
--create-namespace
-f ${{ vars.HELM_VALUES_PATH }}/values.yaml
--set-string theia-certificates.adminApiToken="${ADMIN_API_TOKEN_B64}"
--set theia-certificates.wildcardCertificate="$(cat wildcard.crt)"
--set theia-certificates.wildcardKey="$(cat wildcard.key)"
--set theia-cloud.keycloak.cookieSecret="${{ secrets.THEIA_KEYCLOAK_COOKIE_SECRET }}")

# Only override Theia Cloud component images when a tag is explicitly provided
if [ -n "${THEIA_CLOUD_TAG}" ]; then
HELM_CMD+=(
--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}"
)
fi

# Only override IDE images when a tag is explicitly provided
if [ -n "${IDE_IMAGES_TAG}" ]; then
HELM_CMD+=(
--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-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}"
--set "theia-cloud.preloading.images[10]=ghcr.io/eduide/eduide/langserver-rust:${IDE_IMAGES_TAG}"
--set theia-appdefinitions.defaultImageTag="${IDE_IMAGES_TAG}"
)
fi

# Install/upgrade the Helm chart with all configuration
# --install: Create if it doesn't exist, upgrade if it does
# --create-namespace: Create the namespace if it doesn't exist
# Image tags controlled by two variables: THEIA_CLOUD_TAG and IDE_IMAGES_TAG
helm upgrade --install theia-cloud-combined ./charts/theia-cloud-combined \
--namespace ${{ vars.NAMESPACE }} \
--create-namespace \
-f ${{ vars.HELM_VALUES_PATH }}/values.yaml \
--set-string theia-certificates.adminApiToken="${ADMIN_API_TOKEN_B64}" \
--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/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}"
# Image tag overrides are applied only when non-empty; otherwise values.yaml settings are preserved
"${HELM_CMD[@]}"
Loading