From 02cdb886a7fd6808b03a609ddeed7663d2f2dc5c Mon Sep 17 00:00:00 2001
From: Ivan Starkov <istarkov@gmail.com>
Date: Fri, 12 Apr 2024 11:03:45 +0300
Subject: [PATCH] build: Test staging (Playground) (#3136)

## Description

- [x] - Add inspect-url, domain
- [x] - Add prs deploy and rename to development
- [x] - Fix router to use newer links (immediately before merge)
- [x] - Add link status
- [x] - Test runtime envs then delete tmp

Next PR:
- [ ] - Bundle cli
- [ ] - Use publish from bundled CLI

## Steps for reproduction

1. click button
2. expect xyz

## Code Review

- [ ] hi @kof, I need you to do
  - conceptual review (architecture, feature-correctness)
  - detailed review (read every line)
  - test it on preview

## Before requesting a review

- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")

## Before merging

- [ ] tested locally and on preview environment (preview dev login:
5de6)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env.example`
and the `builder/env-check.js` if mandatory
---
 .github/actions/add-status/action.yaml      |  35 +++++++
 .github/actions/vercel/action.yaml          | 106 ++++++++++++++++++++
 .github/workflows/add-status.yml            |  42 --------
 .github/workflows/vercel-deploy-staging.yml |  75 ++++++++++++++
 _todo_vercel.json => vercel.json            |   0
 5 files changed, 216 insertions(+), 42 deletions(-)
 create mode 100644 .github/actions/add-status/action.yaml
 create mode 100644 .github/actions/vercel/action.yaml
 delete mode 100644 .github/workflows/add-status.yml
 create mode 100644 .github/workflows/vercel-deploy-staging.yml
 rename _todo_vercel.json => vercel.json (100%)

diff --git a/.github/actions/add-status/action.yaml b/.github/actions/add-status/action.yaml
new file mode 100644
index 000000000..9102cc7cc
--- /dev/null
+++ b/.github/actions/add-status/action.yaml
@@ -0,0 +1,35 @@
+name: Add status to commit
+description: Add status to commit
+inputs:
+  url:
+    description: "URL"
+    required: true
+  title:
+    description: "Title"
+    required: true
+  description:
+    description: "Description"
+    required: true
+
+runs:
+  using: "composite"
+  steps:
+    - name: Add URL to vercel deployment through *.prs.webstudio.is
+      uses: actions/github-script@v6
+      with:
+        script: |
+          const branch = context.payload.pull_request?.head?.ref ?? context.payload.ref?.replace('refs/heads/', '')
+          const sha = context.payload.pull_request?.head?.sha ?? context.sha;
+
+          const status = {
+            state: 'success',
+            target_url: '${{ inputs.url }}',
+            description: '${{ inputs.description }}',
+            context: '${{ inputs.title }}'
+          };
+
+          github.rest.repos.createCommitStatus({
+            ...context.repo,
+            sha,
+            ...status
+          });
diff --git a/.github/actions/vercel/action.yaml b/.github/actions/vercel/action.yaml
new file mode 100644
index 000000000..980c64b53
--- /dev/null
+++ b/.github/actions/vercel/action.yaml
@@ -0,0 +1,106 @@
+name: "VERCEL BUILD AND DEPLOY"
+description: "Builds and deploy vercel project"
+
+inputs:
+  vercel-token:
+    description: "Vercel token"
+    required: true
+  vercel-org-id:
+    description: "Vercel Organization ID"
+    required: true
+  vercel-project-id:
+    description: "Vercel Project ID"
+    required: true
+  ref-name:
+    description: "Branch"
+    required: true
+  sha:
+    description: "Sha"
+    required: true
+  environment:
+    description: "Sha"
+    required: true
+
+outputs:
+  domain:
+    description: "Domain"
+    value: ${{ steps.deploy.outputs.domain }}
+  inspect-url:
+    description: "Inspect URL"
+    value: ${{ steps.deploy.outputs.inspect-url }}
+  alias:
+    description: "Alias"
+    value: ${{ steps.alias.outputs.value }}
+
+runs:
+  using: "composite"
+  steps:
+    - id: branch
+      run: |
+        CLEAN_NAME="${GITHUB_REF_NAME/.staging/}"
+        CLEAN_NAME=$( echo "${CLEAN_NAME}" | sed 's/[^a-zA-Z0-9_-]//g' | tr A-Z a-z | tr _ - | sed 's/-\{2,\}/-/g' )
+        echo "value=${CLEAN_NAME}" >> $GITHUB_OUTPUT
+      shell: bash
+
+    - id: short_sha
+      run: |
+        SHORT_SHA=$( echo "value=$(echo ${{ github.sha }} | cut -c1-7)" )
+        echo "value=${SHORT_SHA}" >> $GITHUB_OUTPUT
+      shell: bash
+
+    - name: CREATE VERCEL PROJECT FILE
+      run: |
+        mkdir -p .vercel
+        cat <<"EOF" > .vercel/project.json
+        {
+          "projectId": "${{ inputs.vercel-project-id }}",
+          "orgId": "${{ inputs.vercel-org-id }}",
+          "settings": {
+            "framework": "remix",
+            "devCommand": "pnpm dev",
+            "installCommand": "pnpm install",
+            "buildCommand": "pnpm --filter=@webstudio-is/prisma-client build:prod && pnpm --filter=@webstudio-is/builder build",
+            "outputDirectory": null,
+            "rootDirectory": "apps/builder",
+            "directoryListing": false,
+            "nodeVersion": "18.x"
+          }
+        }
+        EOF
+      shell: bash
+
+    - name: Build
+      run: |
+        vercel build
+      shell: bash
+
+    - name: Deploy
+      id: deploy
+      run: |
+        vercel deploy \
+        --prebuilt \
+        --token ${{ inputs.vercel-token }} \
+        --env SHORT_SHA=${{ steps.short_sha.outputs.value }} \
+        --env BRANCH_NAME=${{ steps.branch.outputs.value }} \
+        --meta GITHUB_SHA=${{ steps.short_sha.outputs.value }} \
+        --meta GITHUB_REF_NAME=${{ steps.branch.outputs.value }} \
+        2> >(tee info.txt >&2) | tee domain.txt
+
+        echo "domain=$(cat ./domain.txt)" >> $GITHUB_OUTPUT
+        echo "inspect-url=$(cat info.txt | grep 'Inspect:' | awk '{print $2}')" >> $GITHUB_OUTPUT
+
+      shell: bash
+
+    - name: Set Alias
+      id: alias
+      run: |
+        ALIAS="${{ steps.branch.outputs.value }}"
+
+        vercel alias set \
+        "${{ steps.deploy.outputs.domain }}" \
+        "${ALIAS}-wstd-00-${{ inputs.environment }}" \
+        --token ${{ inputs.vercel-token }} \
+        --scope getwebstudio
+
+        echo "value=${ALIAS}" >> $GITHUB_OUTPUT
+      shell: bash
diff --git a/.github/workflows/add-status.yml b/.github/workflows/add-status.yml
deleted file mode 100644
index c6a4020af..000000000
--- a/.github/workflows/add-status.yml
+++ /dev/null
@@ -1,42 +0,0 @@
-name: Add status to commit
-
-on:
-  push:
-    branches:
-      - main
-  pull_request_target:
-
-permissions:
-  statuses: write # This is required for the GitHub Script createCommitStatus to work
-
-jobs:
-  add-status:
-    timeout-minutes: 20
-
-    env:
-      DATABASE_URL: postgres://
-      AUTH_SECRET: test
-
-    runs-on: ubuntu-latest
-
-    steps:
-      - name: Add URL to vercel deployment through *.prs.webstudio.is
-        uses: actions/github-script@v6
-        with:
-          script: |
-
-            const branch = context.payload.pull_request?.head?.ref ?? context.payload.ref?.replace('refs/heads/', '')
-            const sha = context.payload.pull_request?.head?.sha ?? context.sha;
-
-            const status = {
-              state: 'success',
-              target_url: `https://${branch.toLowerCase().replace(/[^a-z0-9-]+/g, '')}.prs.webstudio.is`,
-              description: 'click details to see the deployment',
-              context: '⭐ Apps Webstudio URL'
-            };
-
-            github.rest.repos.createCommitStatus({
-              ...context.repo,
-              sha,
-              ...status
-            });
diff --git a/.github/workflows/vercel-deploy-staging.yml b/.github/workflows/vercel-deploy-staging.yml
new file mode 100644
index 000000000..5334bfd92
--- /dev/null
+++ b/.github/workflows/vercel-deploy-staging.yml
@@ -0,0 +1,75 @@
+name: Vercel Deploy Staging
+
+on:
+  push:
+
+# cancel in-progress runs on new commits to same PR (gitub.event.number)
+concurrency:
+  group: vercel-deploy-${{ github.workflow }}-${{ github.event.number || github.sha }}
+  cancel-in-progress: true
+
+permissions:
+  contents: read # to fetch code (actions/checkout)
+  statuses: write # This is required for the GitHub Script createCommitStatus to work
+
+jobs:
+  deployment:
+    # Execute development and staging on staging branches
+    # Execute only development on all other branches
+    strategy:
+      matrix:
+        environment:
+          - staging
+          - development
+        is-staging:
+          - ${{ endsWith(github.ref_name, '.staging') }}
+        exclude:
+          - environment: staging
+            is-staging: false
+
+    environment:
+      name: ${{ matrix.environment }}
+
+    timeout-minutes: 20
+
+    runs-on: ubuntu-latest
+
+    steps:
+      - uses: actions/checkout@v3
+        with:
+          ref: ${{ github.event.pull_request.head.sha || github.sha }} # HEAD commit instead of merge commit
+
+      - uses: pnpm/action-setup@v2.2.4
+      - uses: actions/setup-node@v3
+        with:
+          node-version: "18.x"
+          cache: pnpm
+
+      - uses: ./.github/actions/vercel
+        id: vercel
+        name: Deploy to Vercel
+        with:
+          vercel-token: ${{ secrets.VERCEL_TOKEN }}
+          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
+          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
+          ref-name: ${{ github.ref_name }}
+          sha: ${{ github.sha }}
+          environment: ${{ matrix.environment }}
+
+      - name: Debug Vercel Outputs
+        run: |
+          echo "domain=${{ steps.vercel.outputs.domain }}"
+          echo "inspect-url=${{ steps.vercel.outputs.inspect-url }}"
+          echo "alias=${{ steps.vercel.outputs.alias }}"
+
+      - uses: ./.github/actions/add-status
+        with:
+          title: "⏰ [${{ matrix.environment }}] Vercel Inspection"
+          description: "[${{ matrix.environment }}] Vercel logs"
+          url: "${{ steps.vercel.outputs.inspect-url }}"
+
+      - uses: ./.github/actions/add-status
+        with:
+          title: "⭐ [${{ matrix.environment }}] Apps Webstudio URL"
+          description: "[${{ matrix.environment }}] Site url"
+          url: "https://${{ steps.vercel.outputs.alias }}.${{ matrix.environment }}.webstudio.is"
diff --git a/_todo_vercel.json b/vercel.json
similarity index 100%
rename from _todo_vercel.json
rename to vercel.json