mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 17:31:43 +00:00
[SG-32440] Configure render.com previews for all client PRs (#32574)
Co-authored-by: gitstart-sourcegraph <gitstart@users.noreply.github.com>
This commit is contained in:
parent
644229db0c
commit
a043e2f767
25
.github/workflows/pr-preview.yml
vendored
Normal file
25
.github/workflows/pr-preview.yml
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
name: PR Preview
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, closed]
|
||||
|
||||
jobs:
|
||||
preview-deployment:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Delete PR preview app
|
||||
if: github.event.action == 'closed'
|
||||
run: ./dev/ci/render-pr-preview.sh -d
|
||||
env:
|
||||
RENDER_COM_API_KEY: ${{ secrets.RENDER_COM_API_KEY }}
|
||||
RENDER_COM_OWNER_ID: ${{ secrets.RENDER_COM_OWNER_ID }}
|
||||
|
||||
BUILDKITE_PULL_REQUEST_REPO: "https://github.com/${{ github.repository }}"
|
||||
BUILDKITE_BRANCH: ${{ github.head_ref }}
|
||||
197
dev/ci/render-pr-preview.sh
Executable file
197
dev/ci/render-pr-preview.sh
Executable file
@ -0,0 +1,197 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
# Env variables:
|
||||
# - RENDER_COM_API_KEY (required)
|
||||
# - RENDER_COM_OWNER_ID (required)
|
||||
# - BUILDKITE_BRANCH (optional)
|
||||
# - BUILDKITE_PULL_REQUEST_REPO (optional)
|
||||
# - BUILDKITE_PULL_REQUEST (optional)
|
||||
# - RENDER_PREVIEW_GITHUB_TOKEN (optional)
|
||||
|
||||
print_usage() {
|
||||
echo "Usage: [ -b BRANCH_NAME ] [ -r REPO_URL ] [ -d ]" 1>&2
|
||||
echo "-b: GitHub branch name" 1>&2
|
||||
echo "-r: GitHub repository url" 1>&2
|
||||
echo "-d: Use this flag to delete preview apps" 1>&2
|
||||
}
|
||||
|
||||
urlencode() {
|
||||
echo "$1" | curl -Gso /dev/null -w "%{url_effective}" --data-urlencode @- "" | cut -c 3- | sed -e 's/%0A//'
|
||||
}
|
||||
|
||||
# branch_name: BUILDKITE_BRANCH or current git branch
|
||||
branch_name="${BUILDKITE_BRANCH}"
|
||||
|
||||
if [ -z "${branch_name}" ]; then
|
||||
branch_name=$(git rev-parse --abbrev-ref HEAD)
|
||||
fi
|
||||
|
||||
# repo_url: BUILDKITE_PULL_REQUEST_REPO or current git remote `origin` url
|
||||
# Should be in formats:
|
||||
# - https://github.com/sourcegraph/sourcegraph
|
||||
# - git://github.com/sourcegraph/sourcegraph.git
|
||||
repo_url="${BUILDKITE_PULL_REQUEST_REPO}"
|
||||
|
||||
if [ -z "${repo_url}" ]; then
|
||||
repo_url=$(git config --get remote.origin.url)
|
||||
fi
|
||||
|
||||
while getopts 'b:r:d' flag; do
|
||||
case "${flag}" in
|
||||
d) is_deleting="true" ;;
|
||||
b) branch_name="${OPTARG}" ;;
|
||||
r) repo_url="${OPTARG}" ;;
|
||||
*)
|
||||
print_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Get `{owner}/{repo}` part from GitHub repository url
|
||||
if [[ "$repo_url" =~ ^(https|git):\/\/github\.com\/(.*)$ ]]; then
|
||||
owner_and_repo="${BASH_REMATCH[2]//\.git/}"
|
||||
else
|
||||
echo "Couldn't find owner_and_repo"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
render_api_key="${RENDER_COM_API_KEY}"
|
||||
render_owner_id="${RENDER_COM_OWNER_ID}"
|
||||
pr_number="${BUILDKITE_PULL_REQUEST}"
|
||||
github_api_key="${RENDER_PREVIEW_GITHUB_TOKEN}"
|
||||
|
||||
if [[ -z "${render_api_key}" || -z "${render_owner_id}" ]]; then
|
||||
echo "RENDER_COM_API_KEY or RENDER_COM_OWNER_ID is not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# App name to show on render.com dashboard and use to create
|
||||
# default url: https://<app_name_slug>.onrender.com
|
||||
pr_preview_app_name="sg-web-${branch_name}"
|
||||
|
||||
# Get service id of preview app on render.com with app name (if exists)
|
||||
renderServiceId=$(curl -sS --request GET \
|
||||
--url "https://api.render.com/v1/services?limit=1&type=web_service&name=$(urlencode "$pr_preview_app_name")" \
|
||||
--header 'Accept: application/json' \
|
||||
--header "Authorization: Bearer ${render_api_key}" | jq -r '.[].service.id')
|
||||
|
||||
# Delete preview app with `-d` flag set
|
||||
if [ "${is_deleting}" = "true" ]; then
|
||||
if [ -z "${renderServiceId}" ]; then
|
||||
echo "Render app not found"
|
||||
|
||||
exit 0
|
||||
fi
|
||||
|
||||
curl -sSf -o /dev/null --request DELETE \
|
||||
--url "https://api.render.com/v1/services/${renderServiceId}" \
|
||||
--header 'Accept: application/json' \
|
||||
--header "Authorization: Bearer ${render_api_key}"
|
||||
|
||||
echo "Render app is deleted!"
|
||||
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Create PR app if it hasn't existed yet and get the app url
|
||||
if [ -z "${renderServiceId}" ]; then
|
||||
echo "Creating new pr preview app..."
|
||||
|
||||
# New app is created with following envs
|
||||
# - ENTERPRISE=1
|
||||
# - NODE_ENV=production
|
||||
# - PORT=3080 // render.com uses this env for mapping default https port
|
||||
# - ENTERPRISE=1
|
||||
# - SOURCEGRAPH_API_URL=https://k8s.sgdev.org
|
||||
# - WEBPACK_SERVE_INDEX=true
|
||||
|
||||
pr_preview_url=$(curl -sSf --request POST \
|
||||
--url https://api.render.com/v1/services \
|
||||
--header 'Accept: application/json' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--header "Authorization: Bearer ${render_api_key}" \
|
||||
--data "
|
||||
{
|
||||
\"autoDeploy\": \"yes\",
|
||||
\"envVars\": [
|
||||
{
|
||||
\"key\": \"ENTERPRISE\",
|
||||
\"value\": \"1\"
|
||||
},
|
||||
{
|
||||
\"key\": \"NODE_ENV\",
|
||||
\"value\": \"production\"
|
||||
},
|
||||
{
|
||||
\"key\": \"PORT\",
|
||||
\"value\": \"3080\"
|
||||
},
|
||||
{
|
||||
\"key\": \"SOURCEGRAPH_API_URL\",
|
||||
\"value\": \"https://k8s.sgdev.org\"
|
||||
},
|
||||
{
|
||||
\"key\": \"WEBPACK_SERVE_INDEX\",
|
||||
\"value\": \"true\"
|
||||
}
|
||||
],
|
||||
\"serviceDetails\": {
|
||||
\"pullRequestPreviewsEnabled\": \"no\",
|
||||
\"envSpecificDetails\": {
|
||||
\"buildCommand\": \"dev/ci/yarn-build.sh client/web\",
|
||||
\"startCommand\": \"yarn workspace @sourcegraph/web serve:prod\"
|
||||
},
|
||||
\"numInstances\": 1,
|
||||
\"plan\": \"starter\",
|
||||
\"region\": \"oregon\",
|
||||
\"env\": \"node\"
|
||||
},
|
||||
\"type\": \"web_service\",
|
||||
\"name\": \"${pr_preview_app_name}\",
|
||||
\"ownerId\": \"${render_owner_id}\",
|
||||
\"repo\": \"${repo_url}\",
|
||||
\"branch\": \"${branch_name}\"
|
||||
}
|
||||
" | jq -r '.service.serviceDetails.url')
|
||||
else
|
||||
echo "Found preview id: ${renderServiceId}, getting preview url..."
|
||||
|
||||
pr_preview_url=$(curl -sSf --request GET \
|
||||
--url "https://api.render.com/v1/services/${renderServiceId}" \
|
||||
--header 'Accept: application/json' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--header "Authorization: Bearer ${render_api_key}" | jq -r '.serviceDetails.url')
|
||||
fi
|
||||
|
||||
echo "Preview url: ${pr_preview_url}"
|
||||
|
||||
if [[ -n "${github_api_key}" && -n "${pr_number}" ]]; then
|
||||
|
||||
# GitHub pull request number and GitHub api token are set
|
||||
# Appending `App Preview` section into PR description if it hasn't existed yet
|
||||
github_pr_api_url="https://api.github.com/repos/${owner_and_repo}/pulls/${pr_number}"
|
||||
|
||||
pr_description=$(curl -sSf --request GET \
|
||||
--url "${github_pr_api_url}" \
|
||||
--user "apikey:${github_api_key}" \
|
||||
--header 'Accept: application/vnd.github.v3+json' \
|
||||
--header 'Content-Type: application/json' | jq -r '.body')
|
||||
|
||||
if [[ "${pr_description}" != *"## App preview"* ]]; then
|
||||
echo "Updating PR #${pr_number} in ${owner_and_repo} description"
|
||||
|
||||
pr_description=$(echo -e "${pr_description}\n## App preview:\n- [Link](${pr_preview_url})\n" | jq -Rs .)
|
||||
|
||||
curl -sSf -o /dev/null --request PATCH \
|
||||
--url "${github_pr_api_url}" \
|
||||
--user "apikey:${github_api_key}" \
|
||||
--header 'Accept: application/vnd.github.v3+json' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data "{ \"body\": ${pr_description} }"
|
||||
else
|
||||
echo "PR #${pr_number} in ${owner_and_repo} description already has \"App preview\" section"
|
||||
fi
|
||||
fi
|
||||
@ -21,6 +21,7 @@ The default run type.
|
||||
|
||||
- Pipeline for `Client` changes:
|
||||
- **Pipeline setup**: Trigger async
|
||||
- Client PR preview
|
||||
- **Linters and static analysis**: Prettier, Misc linters, Yarn deduplicate lint
|
||||
- **Client checks**: Puppeteer tests prep, Puppeteer tests chunk #1, Puppeteer tests chunk #2, Puppeteer tests chunk #3, Puppeteer tests chunk #4, Puppeteer tests chunk #5, Puppeteer tests chunk #6, Puppeteer tests chunk #7, Puppeteer tests chunk #8, Puppeteer tests chunk #9, Puppeteer tests finalize, Upload Storybook to Chromatic, Test (all), Build, Enterprise build, Test (client/web), Puppeteer tests for chrome extension, Test (client/browser), ESLint, Build TS, Stylelint
|
||||
- Upload build trace
|
||||
|
||||
@ -815,3 +815,12 @@ func uploadBuildeventTrace() operations.Operation {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Request render.com to create client preview app for current PR
|
||||
// Preview is deleted from render.com in GitHub Action when PR is closed
|
||||
func prPreview() operations.Operation {
|
||||
return func(pipeline *bk.Pipeline) {
|
||||
pipeline.AddStep(":globe_with_meridians: Client PR preview",
|
||||
bk.Cmd("dev/ci/render-pr-preview.sh"))
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,6 +92,8 @@ func GeneratePipeline(c Config) (*bk.Pipeline, error) {
|
||||
// set it up separately from CoreTestOperations
|
||||
ops.Merge(operations.NewNamedSet(operations.PipelineSetupSetName,
|
||||
triggerAsync(buildOptions)))
|
||||
|
||||
ops.Append(prPreview())
|
||||
}
|
||||
ops.Merge(CoreTestOperations(c.Diff, CoreTestOperationsOptions{MinimumUpgradeableVersion: minimumUpgradeableVersion}))
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user