Skip to content

Publish Theia IDE Preview Deployment #53

Publish Theia IDE Preview Deployment

Publish Theia IDE Preview Deployment #53

name: Publish Theia IDE Preview Deployment
permissions:
contents: read
pull-requests: write
on:
workflow_dispatch:
inputs:
tag:
description: The image's tag
required: true
default: next
theia_version:
description: Theia Version
required: false
default: next
pull_request:
branches: [master]
types:
- opened
- synchronize
- reopened
schedule:
- cron: '0 13 * * 0'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
build:
name: Build Theia IDE Preview image
runs-on: ubuntu-latest
steps:
# Check out the repository
- name: Checkout
uses: actions/checkout@v2
# Set up Node.js environment
- name: Use Node.js 20.x
uses: actions/setup-node@v3
with:
node-version: 20.x
registry-url: 'https://registry.npmjs.org'
# Set up Python environment
- name: Use Python 3.11
uses: actions/setup-python@v4
with:
python-version: '3.11'
# Install system dependencies required for native-keymap
- name: Install dependencies for native-keymap
run: sudo apt-get update && sudo apt-get install -y libx11-dev libxkbfile-dev
# Set up Docker Buildx for building Docker images
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1
# Determine the Theia version to update to. May be empty
- name: Set the Theia version
id: set-theia-version
run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
echo "THEIA_VERSION=${{ github.event.inputs.theia_version }}" >> $GITHUB_ENV
elif [ "${{ github.event_name }}" == "pull_request" ]; then
echo "THEIA_VERSION=" >> $GITHUB_ENV
else
echo "THEIA_VERSION=next" >> $GITHUB_ENV
fi
# Run the Theia update process if a specific version is set
- name: Run Theia update if version is specified
if: ${{ env.THEIA_VERSION != '' }}
run: |
yarn && yarn update:theia ${THEIA_VERSION} && yarn update:theia:children ${THEIA_VERSION} && yarn
# Determine the image tag to use for Docker based on the event
- name: Set image tag
id: set-tag
run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
echo "IMAGE_TAG=${{ github.event.inputs.tag }}" >> $GITHUB_ENV
elif [ "${{ github.event_name }}" == "pull_request" ]; then
echo "IMAGE_TAG=pr-${{ github.event.pull_request.number }}" >> $GITHUB_ENV
elif [ "${{ github.event_name }}" == "schedule" ]; then
echo "IMAGE_TAG=weekly" >> $GITHUB_ENV
else
echo "IMAGE_TAG=other" >> $GITHUB_ENV
fi
# Authenticate to Google Cloud using a service account
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@71f986410dfbc7added4569d411d040a91dc6935 # v2.1.8
with:
credentials_json: ${{ secrets.GCP_SA_KEY }}
project_id: kubernetes-238012
create_credentials_file: true
# Set up Google Cloud SDK
- name: Setup Google Cloud SDK
uses: google-github-actions/setup-gcloud@77e7a554d41e2ee56fc945c52dfd3f33d12def9a # v2.1.4
# Configure Docker to use Google's Artifact Registry
- name: Configure Docker for Artifact Registry
run: |
gcloud auth configure-docker europe-west3-docker.pkg.dev
# Update or create a bot comment on pull requests
- name: Update bot comment
if: github.event_name == 'pull_request'
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea #7.0.1
with:
script: |
const {data: comments} = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.number,
})
const botComment = comments.find(comment => comment.user.id === 41898282)
const commentBody = "Thank you for opening the PR!\n\nThis comment will be replaced with a link to a Preview deployment as soon as it is ready."
if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: commentBody
})
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.number,
body: commentBody
})
}
# Build and push the Docker image
- name: Build Docker image
uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 # v6.10.0
with:
context: .
file: browser.Dockerfile
push: true
tags: |
europe-west3-docker.pkg.dev/kubernetes-238012/theia-ide-preview/theia-ide-preview:${{ env.IMAGE_TAG }}
# Get credentials for the Google Kubernetes Engine cluster
- name: Get GKE Credentials
uses: google-github-actions/get-gke-credentials@d0cee45012069b163a631894b98904a9e6723729 # v2.3.3
with:
cluster_name: github-theia-ide-preview
location: europe-west3-c
# List sessions running in the Theia Cloud namespace
- name: List sessions in theia-cloud namespace
run: kubectl get sessions -n theia-cloud
# List app definitions running in the Theia Cloud namespace
- name: List apps in theia-cloud namespace
run: kubectl get appdefinitions -n theia-cloud
# Delete existing app definition if it exists
- name: Delete app definition if existent
run: kubectl delete appdefinitions theia-ide-${{ env.IMAGE_TAG }} -n theia-cloud || true
# Delete existing sessions related to the specific app definition
- name: Delete existing sessions
run: kubectl get sessions -n theia-cloud -o json | jq -r '.items[] | select(.spec.appDefinition == "theia-ide-${{ env.IMAGE_TAG }}") | .metadata.name' | xargs -r kubectl delete sessions -n theia-cloud
# Create a new app definition for the deployment
- name: Create app definition
run: |
cat <<EOF | kubectl apply -f -
apiVersion: theia.cloud/v1beta10
kind: AppDefinition
metadata:
name: theia-ide-${{ env.IMAGE_TAG }}
namespace: theia-cloud
spec:
downlinkLimit: 30000
image: europe-west3-docker.pkg.dev/kubernetes-238012/theia-ide-preview/theia-ide-preview:${{ env.IMAGE_TAG }}
imagePullPolicy: Always
ingressname: theia-cloud-demo-ws-ingress
limitsCpu: "2"
limitsMemory: 500M
maxInstances: 3
minInstances: 0
mountPath: /home/project/persisted
name: theia-ide-${{ env.IMAGE_TAG }}
port: 3000
requestsCpu: "100m"
requestsMemory: 300M
timeout: 15
uid: 101
uplinkLimit: 30000
EOF
# Update the bot comment in pull requests with a link to the deployment
- name: Update bot comment with URL
if: github.event_name == 'pull_request'
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea #7.0.1
with:
script: |
const {data: comments} = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.number,
})
const botComment = comments.find(comment => comment.user.id === 41898282)
const commentBody = "Preview deployment created at https://launch.theia-ide-preview.eclipsesource-munich.com/?appDef=theia-ide-${{ env.IMAGE_TAG }}\n\nWhen the deployment is cleaned up, this link will be removed again."
if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: commentBody
})
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.number,
body: commentBody
})
}