diff --git a/.github/workflows/build-deploy-preview.yml b/.github/workflows/build-deploy-preview.yml new file mode 100644 index 0000000000..22753c3158 --- /dev/null +++ b/.github/workflows/build-deploy-preview.yml @@ -0,0 +1,22 @@ +# If someone with write access comments "/build-deploy-preview" on a pull request, emit a repository_dispatch event +name: Build Deploy Preview + +on: + issue_comment: + types: [created] + +jobs: + build-deploy-preview: + runs-on: ubuntu-latest + # Only run for PRs, not issue comments + if: | + github.event.issue.pull_request + steps: + + - name: Slash Command Dispatch + uses: peter-evans/slash-command-dispatch@v3 + with: + issue-type: pull-request + token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + commands: | + build-deploy-preview diff --git a/.github/workflows/on-demand-build-docker-image-deploy-preview.yml b/.github/workflows/on-demand-build-docker-image-deploy-preview.yml new file mode 100644 index 0000000000..28f454be14 --- /dev/null +++ b/.github/workflows/on-demand-build-docker-image-deploy-preview.yml @@ -0,0 +1,141 @@ +name: On demand build Docker image and deploy preview + +on: + # This workflow is only triggered by the `/build-deploy-preview` command dispatch + repository_dispatch: + types: [ build-deploy-preview-command ] + +jobs: + notify: + runs-on: ubuntu-latest + steps: + # This step creates a comment on the PR with a link to this workflow run. + - name: Add a comment on the PR with link to workflow run + uses: peter-evans/create-or-update-comment@v2 + with: + issue-number: ${{ github.event.client_payload.pull_request.number }} + body: | + Deploying Your Preview: <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}>. + Workflow: `${{ github.workflow }}`. + PR: ${{ github.event.client_payload.pull_request.number }}. + URL: https://${{ github.event.client_payload.pull_request.number }}-ce.appsmith.com + + server-build: + name: server-build + uses: ./.github/workflows/server-build.yml + secrets: inherit + with: + pr: ${{ github.event.client_payload.pull_request.number }} + + client-build: + name: client-build + uses: ./.github/workflows/client-build.yml + secrets: inherit + with: + pr: ${{ github.event.client_payload.pull_request.number }} + + rts-build: + name: rts-build + uses: ./.github/workflows/rts-build.yml + secrets: inherit + with: + pr: ${{ github.event.client_payload.pull_request.number }} + + push-image: + needs: [client-build, rts-build, server-build] + runs-on: ubuntu-latest + + if: success() + + steps: + + - name: Set up Depot CLI + uses: depot/setup-action@v1 + + # Check out merge commit + - name: Checkout PR + uses: actions/checkout@v3 + with: + ref: "refs/pull/${{ github.event.client_payload.pull_request.number }}/merge" + + # Timestamp will be used to create cache key + - id: timestamp + run: echo "timestamp=$(date +'%Y-%m-%dT%H:%M:%S')" >> $GITHUB_OUTPUT + + # get Git-hash will be used to create cache key + - id: git_hash + run: echo "git_hash=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + + - name: Download the react build artifact + uses: actions/download-artifact@v3 + with: + name: build + path: app/client/build + + - name: Download the server build artifact + uses: actions/download-artifact@v3 + with: + name: build + path: app/server/dist + + - name: Download the rts build artifact + uses: actions/download-artifact@v3 + with: + name: rts-dist + path: app/rts/dist + + - name: Untar the rts folder + run: | + tar -xvf app/rts/dist/rts-dist.tar -C app/rts/ + echo "Cleaning up the tar files" + rm app/rts/dist/rts-dist.tar + + - name: Push to Docker Hub + uses: docker/build-push-action@v1 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + repository: ${{ secrets.DOCKER_HUB_ORGANIZATION }}/appsmith-ce + tags: ${{ steps.git_hash.outputs.git_hash }} + outputs: + imageHash: ${{ steps.git_hash.outputs.git_hash }} + + build-deploy-preview: + needs: [push-image] + runs-on: ubuntu-latest + defaults: + run: + working-directory: "." + + if: success() + steps: + + - name: Checkout PR + uses: actions/checkout@v3 + with: + ref: "refs/pull/${{ github.event.client_payload.pull_request.number }}/merge" + fetch-depth: 0 + + - name: Install relevant packages + run: | + which aws + sudo apt update -q && sudo apt install -y curl unzip less jq + curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.23.6/bin/linux/amd64/kubectl && \ + sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl && \ + curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 && \ + chmod 700 get_helm.sh; ./get_helm.sh + + - name: Deploy Helm chart + env: + AWS_ROLE_ARN: ${{ secrets.APPSMITH_EKS_AWS_ROLE_ARN }} + AWS_ACCESS_KEY_ID: ${{ secrets.APPSMITH_CI_AWS_SECRET_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.APPSMITH_CI_AWS_SECRET_ACCESS_KEY }} + IMAGE_HASH: ${{ needs.push-image.outputs.imageHash }} + AWS_RELEASE_CERT: ${{ secrets.APPSMITH_AWS_RELEASE_CERT_RELEASE }} + DOCKER_HUB_ORGANIZATION: ${{ secrets.DOCKER_HUB_ORGANIZATION }} + DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }} + DOCKER_HUB_ACCESS_TOKEN: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + PULL_REQUEST_NUMBER: ${{ github.event.client_payload.pull_request.number }} + run: | + echo "environment variables set to deploy the image" $IMAGE_HASH + /bin/bash ./scripts/deploy_preview.sh diff --git a/scripts/deploy_preview.sh b/scripts/deploy_preview.sh new file mode 100755 index 0000000000..31f9c4525e --- /dev/null +++ b/scripts/deploy_preview.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# Params are in environment variables as PARAM_{SLUG}, e.g. PARAM_USER_ID + +# Configure the AWS & kubectl environment + +mkdir ~/.aws; touch ~/.aws/config + +echo "[default] +aws_access_key_id = $AWS_ACCESS_KEY_ID +aws_secret_access_key = $AWS_SECRET_ACCESS_KEY" > ~/.aws/credentials + +echo "[default] +[profile eksci] +role_arn= $AWS_ROLE_ARN +output = json +region=ap-south-1 +source_profile = default" > ~/.aws/config + +export region=ap-south-1 +export cluster_name=uat-cluster + +echo "Region: $region" +echo "Cluster name: $cluster_name" +echo "Pull Request Number: $PULL_REQUEST_NUMBER" + +sts_output=$(aws sts assume-role --role-arn env.AWS_ROLE_ARN --role-session-name ekscisession +export AWS_ACCESS_KEY_ID=$(echo $sts_output | jq -r '.Credentials''.AccessKeyId');\ +export AWS_SECRET_ACCESS_KEY=$(echo $sts_output | jq -r '.Credentials''.SecretAccessKey');\ +export AWS_SESSION_TOKEN=$(echo $sts_output | jq -r '.Credentials''.SessionToken'); + +export NAMESPACE="$PULL_REQUEST_NUMBER"ce +export SECRET="$PULL_REQUEST_NUMBER"ce +export DOMAINNAME="$PULL_REQUEST_NUMBER"-ce.appsmith.com +export HELMCHART="appsmith" +export HELMCHART_URL="http://helm.appsmith.com" +export HELMCHART_VERSION="2.0.0" + +aws eks update-kubeconfig --region $region --name $cluster_name --profile eksci + +echo "Set the default namespace" +kubectl config set-context --current --namespace=default + +echo "Getting the pods" +kubectl get pods + +echo "Delete previously created namespace" +kubectl delete ns $NAMESPACE || echo "true" + +echo "Use kubernetes secret to Pull Image" +kubectl create ns $NAMESPACE +kubectl create secret docker-registry $SECRET \ + --docker-server=https://index.docker.io/v1/ \ + --docker-username=$DOCKER_HUB_USERNAME \ + --docker-password=$DOCKER_HUB_ACCESS_TOKEN -n $NAMESPACE + +echo "Add appsmith-ce to helm repo" +AWS_REGION=ap-south-1 helm repo add $HELMCHART $HELMCHART_URL + +echo "Deploy appsmith helm chart" +helm install appsmith/appsmith --generate-name -n $NAMESPACE \ + --create-namespace --set image.repository=$DOCKER_HUB_ORGANIZATION/appsmith-ce --set image.tag=$IMAGE_HASH \ + --set image.pullSecrets=$SECRET --set redis.enabled=false --set mongodb.enabled=false --set ingress.enabled=true \ + --set "ingress.annotations.service\.beta\.kubernetes\.io/aws-load-balancer-ssl-cert=$AWS_RELEASE_CERT" \ + --set "ingress.hosts[0].host=$DOMAINNAME, ingress.hosts[0].paths[0].path=/, ingress.hosts[0].paths[0].pathType=Prefix" \ + --set ingress.className="nginx" --set autoupdate.enabled="true" --version $HELMCHART_VERSION