mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
ci: implement automatic upgrade of PR deployment (#8876)
This commit is contained in:
committed by
GitHub
parent
d3991fac26
commit
b47bd7ccb5
@@ -1,7 +1,7 @@
|
||||
name: Cleanup PR deployment and image
|
||||
on:
|
||||
pull_request:
|
||||
types: [closed]
|
||||
types: closed
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
pr_number:
|
||||
@@ -63,5 +63,11 @@ jobs:
|
||||
(
|
||||
curl -X DELETE "https://api.cloudflare.com/client/v4/zones/${{ secrets.PR_DEPLOYMENTS_ZONE_ID }}/dns_records/$record_id" \
|
||||
-H "Authorization: Bearer ${{ secrets.PR_DEPLOYMENTS_CLOUDFLARE_API_TOKEN }}" \
|
||||
-H "Content-Type:application/json"
|
||||
-H "Content-Type:application/json" | jq -r '.success'
|
||||
) || echo "DNS record not found"
|
||||
|
||||
- name: "Delete certificate"
|
||||
if: ${{ github.event.pull_request.merged == true }}
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
kuebctl delete certificate "pr${{ steps.pr_number.outputs.PR_NUMBER }}-tls" -n pr-deployment-certs || echo "certificate not found"
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
# This action will trigger when a PR is commented on with `/deploy-pr` or when the workflow is manually triggered.
|
||||
# This action will trigger when
|
||||
# 1. when the workflow is manually triggered
|
||||
# 2. ./scripts/deploy_pr.sh is run locally
|
||||
# 3. when a PR is updated
|
||||
name: Deploy PR
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created, edited]
|
||||
pull_request:
|
||||
types: synchronize
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
pr_number:
|
||||
@@ -29,12 +32,12 @@ permissions:
|
||||
pull-requests: write
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-PR-${{ (github.event.issue.number) || (github.event.inputs.pr_number) }}
|
||||
group: ${{ github.workflow }}-PR-${{ github.event.pull_request.number || github.event.inputs.pr_number }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
pr_commented:
|
||||
if: (github.event_name == 'issue_comment' && contains(github.event.comment.body, '/deploy-pr') && (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'COLLABORATOR' || github.event.comment.author_association == 'OWNER')) || github.event_name == 'workflow_dispatch'
|
||||
get_info:
|
||||
if: github.event_name == 'workflow_dispatch' || github.event_name == 'pull_request'
|
||||
outputs:
|
||||
PR_NUMBER: ${{ steps.pr_info.outputs.PR_NUMBER }}
|
||||
PR_TITLE: ${{ steps.pr_info.outputs.PR_TITLE }}
|
||||
@@ -42,6 +45,8 @@ jobs:
|
||||
PR_BRANCH: ${{ steps.pr_info.outputs.PR_BRANCH }}
|
||||
CODER_BASE_IMAGE_TAG: ${{ steps.set_tags.outputs.CODER_BASE_IMAGE_TAG }}
|
||||
CODER_IMAGE_TAG: ${{ steps.set_tags.outputs.CODER_IMAGE_TAG }}
|
||||
NEW: ${{ steps.check_deployment.outputs.new }}
|
||||
BUILD: ${{ steps.filter.outputs.all_count > steps.filter.outputs.ignored_count }}
|
||||
|
||||
runs-on: "ubuntu-latest"
|
||||
steps:
|
||||
@@ -49,11 +54,7 @@ jobs:
|
||||
id: pr_info
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
if [[ ${{ github.event_name }} == "workflow_dispatch" ]]; then
|
||||
PR_NUMBER=${{ github.event.inputs.pr_number }}
|
||||
else
|
||||
PR_NUMBER=${{ github.event.issue.number }}
|
||||
fi
|
||||
PR_NUMBER=${{ github.event.inputs.pr_number || github.event.pull_request.number }}
|
||||
PR_TITLE=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/coder/coder/pulls/$PR_NUMBER | jq -r '.title')
|
||||
PR_BRANCH=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/coder/coder/pulls/$PR_NUMBER | jq -r '.head.ref')
|
||||
echo "PR_URL=https://github.com/coder/coder/pull/$PR_NUMBER" >> $GITHUB_OUTPUT
|
||||
@@ -71,28 +72,98 @@ jobs:
|
||||
CODER_BASE_IMAGE_TAG: ghcr.io/coder/coder-preview-base:pr${{ steps.pr_info.outputs.PR_NUMBER }}
|
||||
CODER_IMAGE_TAG: ghcr.io/coder/coder-preview:pr${{ steps.pr_info.outputs.PR_NUMBER }}
|
||||
|
||||
- name: Comment on PR
|
||||
id: comment_id
|
||||
if: github.event_name == 'issue_comment'
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
- name: Set up kubeconfig
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
mkdir -p ~/.kube
|
||||
echo "${{ secrets.PR_DEPLOYMENTS_KUBECONFIG }}" > ~/.kube/config
|
||||
export KUBECONFIG=~/.kube/config
|
||||
|
||||
- name: Check if the helm deployment already exists
|
||||
id: check_deployment
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
if helm status "pr${{ steps.pr_info.outputs.PR_NUMBER }}" --namespace "pr${{ steps.pr_info.outputs.PR_NUMBER }}" > /dev/null 2>&1; then
|
||||
echo "Deployment already exists. Skipping deployment."
|
||||
new=false
|
||||
else
|
||||
echo "Deployment doesn't exist. Creating a new one."
|
||||
new=true
|
||||
fi
|
||||
echo "new=$new" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Find Comment
|
||||
uses: peter-evans/find-comment@v2
|
||||
id: fc
|
||||
with:
|
||||
issue-number: ${{ steps.pr_info.outputs.PR_NUMBER }}
|
||||
comment-author: "github-actions[bot]"
|
||||
body-includes: ":rocket:"
|
||||
direction: last
|
||||
|
||||
- name: Comment on PR
|
||||
id: comment_id
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
with:
|
||||
comment-id: ${{ steps.fc.outputs.comment-id }}
|
||||
issue-number: ${{ steps.pr_info.outputs.PR_NUMBER }}
|
||||
edit-mode: replace
|
||||
body: |
|
||||
---
|
||||
:rocket: Deploying PR ${{ steps.pr_info.outputs.PR_NUMBER }} ...
|
||||
:warning: This deployment will be deleted when the PR is closed.
|
||||
reactions: "+1"
|
||||
---
|
||||
reactions: eyes
|
||||
reactions-edit-mode: replace
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ steps.pr_info.outputs.PR_BRANCH }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Check changed files
|
||||
uses: dorny/paths-filter@v2
|
||||
id: filter
|
||||
with:
|
||||
filters: |
|
||||
all:
|
||||
- "**"
|
||||
ignored:
|
||||
- "docs/**"
|
||||
- "README.md"
|
||||
- "examples/web-server/**"
|
||||
- "examples/monitoring/**"
|
||||
- "examples/lima/**"
|
||||
- ".github/**"
|
||||
- "offlinedocs/**"
|
||||
- ".devcontainer/**"
|
||||
- "helm/**"
|
||||
- "*[^g][^o][^.][^s][^u][^m]*"
|
||||
- "*[^g][^o][^.][^m][^o][^d]*"
|
||||
- "*[^M][^a][^k][^e][^f][^i][^l][^e]*"
|
||||
- "scripts/**/*[^D][^o][^c][^k][^e][^r][^f][^i][^l][^e]*"
|
||||
- "scripts/**/*[^D][^o][^c][^k][^e][^r][^f][^i][^l][^e][.][b][^a][^s][^e]*"
|
||||
|
||||
- name: Print number of changed files
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
echo "Total number of changed files: ${{ steps.filter.outputs.all_count }}"
|
||||
echo "Number of ignored files: ${{ steps.filter.outputs.ignored_count }}"
|
||||
|
||||
build:
|
||||
needs: pr_commented
|
||||
needs: get_info
|
||||
# Skips the build job if the workflow was triggered by a workflow_dispatch event and the skip_build input is set to true
|
||||
# or if the workflow was triggered by an issue_comment event and the comment body contains --skip-build
|
||||
if: (github.event_name == 'workflow_dispatch' && github.event.inputs.skip_build == 'false') || (github.event_name == 'issue_comment' && contains(github.event.comment.body, '--skip-build') != true)
|
||||
# alwyas run the build job if the workflow was triggered by a pull_request event
|
||||
if: |
|
||||
(github.event_name == 'workflow_dispatch' && github.event.inputs.skip_build == 'false') ||
|
||||
(github.event_name == 'pull_request' && needs.get_info.outputs.NEW == 'false')
|
||||
runs-on: ${{ github.repository_owner == 'coder' && 'buildjet-8vcpu-ubuntu-2204' || 'ubuntu-latest' }}
|
||||
env:
|
||||
DOCKER_CLI_EXPERIMENTAL: "enabled"
|
||||
CODER_IMAGE_TAG: ${{ needs.pr_commented.outputs.CODER_IMAGE_TAG }}
|
||||
PR_NUMBER: ${{ needs.pr_commented.outputs.PR_NUMBER }}
|
||||
PR_BRANCH: ${{ needs.pr_commented.outputs.PR_BRANCH }}
|
||||
CODER_IMAGE_TAG: ${{ needs.get_info.outputs.CODER_IMAGE_TAG }}
|
||||
PR_NUMBER: ${{ needs.get_info.outputs.PR_NUMBER }}
|
||||
PR_BRANCH: ${{ needs.get_info.outputs.PR_BRANCH }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
@@ -101,15 +172,19 @@ jobs:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node
|
||||
if: needs.get_info.outputs.BUILD == 'true'
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: Setup Go
|
||||
if: needs.get_info.outputs.BUILD == 'true'
|
||||
uses: ./.github/actions/setup-go
|
||||
|
||||
- name: Setup sqlc
|
||||
if: needs.get_info.outputs.BUILD == 'true'
|
||||
uses: ./.github/actions/setup-sqlc
|
||||
|
||||
- name: GHCR Login
|
||||
if: needs.get_info.outputs.BUILD == 'true'
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
@@ -117,6 +192,7 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push Linux amd64 Docker image
|
||||
if: needs.get_info.outputs.BUILD == 'true'
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
go mod download
|
||||
@@ -133,19 +209,27 @@ jobs:
|
||||
build/coder_linux_amd64
|
||||
|
||||
deploy:
|
||||
needs: [build, pr_commented]
|
||||
needs: [build, get_info]
|
||||
# Run deploy job only if build job was successful or skipped
|
||||
if: always() && (needs.build.result == 'success' || needs.build.result == 'skipped') && needs.pr_commented.result == 'success'
|
||||
if: always() && (needs.build.result == 'success' || needs.build.result == 'skipped') && needs.get_info.result == 'success'
|
||||
runs-on: "ubuntu-latest"
|
||||
env:
|
||||
CODER_IMAGE_TAG: ${{ needs.pr_commented.outputs.CODER_IMAGE_TAG }}
|
||||
PR_NUMBER: ${{ needs.pr_commented.outputs.PR_NUMBER }}
|
||||
PR_TITLE: ${{ needs.pr_commented.outputs.PR_TITLE }}
|
||||
PR_URL: ${{ needs.pr_commented.outputs.PR_URL }}
|
||||
PR_BRANCH: ${{ needs.pr_commented.outputs.PR_BRANCH }}
|
||||
PR_DEPLOYMENT_ACCESS_URL: "pr${{ needs.pr_commented.outputs.PR_NUMBER }}.${{ secrets.PR_DEPLOYMENTS_DOMAIN }}"
|
||||
CODER_IMAGE_TAG: ${{ needs.get_info.outputs.CODER_IMAGE_TAG }}
|
||||
PR_NUMBER: ${{ needs.get_info.outputs.PR_NUMBER }}
|
||||
PR_TITLE: ${{ needs.get_info.outputs.PR_TITLE }}
|
||||
PR_URL: ${{ needs.get_info.outputs.PR_URL }}
|
||||
PR_BRANCH: ${{ needs.get_info.outputs.PR_BRANCH }}
|
||||
PR_DEPLOYMENT_ACCESS_URL: "pr${{ needs.get_info.outputs.PR_NUMBER }}.${{ secrets.PR_DEPLOYMENTS_DOMAIN }}"
|
||||
steps:
|
||||
- name: Set up kubeconfig
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
mkdir -p ~/.kube
|
||||
echo "${{ secrets.PR_DEPLOYMENTS_KUBECONFIG }}" > ~/.kube/config
|
||||
export KUBECONFIG=~/.kube/config
|
||||
|
||||
- name: Check if image exists
|
||||
if: needs.get_info.outputs.NEW == 'true'
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
foundTag=$(curl -fsSL https://github.com/coder/coder/pkgs/container/coder-preview | grep -o ${{ env.CODER_IMAGE_TAG }} | head -n 1)
|
||||
@@ -157,27 +241,20 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Add DNS record to Cloudflare
|
||||
if: needs.get_info.outputs.NEW == 'true'
|
||||
run: |
|
||||
(
|
||||
curl -X POST "https://api.cloudflare.com/client/v4/zones/${{ secrets.PR_DEPLOYMENTS_ZONE_ID }}/dns_records" \
|
||||
-H "Authorization: Bearer ${{ secrets.PR_DEPLOYMENTS_CLOUDFLARE_API_TOKEN }}" \
|
||||
-H "Content-Type:application/json" \
|
||||
--data '{"type":"CNAME","name":"*.${{ env.PR_DEPLOYMENT_ACCESS_URL }}","content":"${{ env.PR_DEPLOYMENT_ACCESS_URL }}","ttl":1,"proxied":false}'
|
||||
)
|
||||
curl -X POST "https://api.cloudflare.com/client/v4/zones/${{ secrets.PR_DEPLOYMENTS_ZONE_ID }}/dns_records" \
|
||||
-H "Authorization: Bearer ${{ secrets.PR_DEPLOYMENTS_CLOUDFLARE_API_TOKEN }}" \
|
||||
-H "Content-Type:application/json" \
|
||||
--data '{"type":"CNAME","name":"*.${{ env.PR_DEPLOYMENT_ACCESS_URL }}","content":"${{ env.PR_DEPLOYMENT_ACCESS_URL }}","ttl":1,"proxied":false}'
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ env.PR_BRANCH }}
|
||||
|
||||
- name: Set up kubeconfig
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
mkdir -p ~/.kube
|
||||
echo "${{ secrets.PR_DEPLOYMENTS_KUBECONFIG }}" > ~/.kube/config
|
||||
export KUBECONFIG=~/.kube/config
|
||||
|
||||
- name: Create PR namespace
|
||||
if: needs.get_info.outputs.NEW == 'true'
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
# try to delete the namespace, but don't fail if it doesn't exist
|
||||
@@ -185,6 +262,7 @@ jobs:
|
||||
kubectl create namespace "pr${{ env.PR_NUMBER }}"
|
||||
|
||||
- name: Check and Create Certificate
|
||||
if: needs.get_info.outputs.NEW == 'true'
|
||||
run: |
|
||||
# Using kubectl to check if a Certificate resource already exists
|
||||
# we are doing this to avoid letsenrypt rate limits
|
||||
@@ -216,6 +294,7 @@ jobs:
|
||||
)
|
||||
|
||||
- name: Set up PostgreSQL database
|
||||
if: needs.get_info.outputs.NEW == 'true'
|
||||
run: |
|
||||
helm repo add bitnami https://charts.bitnami.com/bitnami
|
||||
helm install coder-db bitnami/postgresql \
|
||||
@@ -227,28 +306,8 @@ jobs:
|
||||
kubectl create secret generic coder-db-url -n pr${{ env.PR_NUMBER }} \
|
||||
--from-literal=url="postgres://coder:coder@coder-db-postgresql.pr${{ env.PR_NUMBER }}.svc.cluster.local:5432/coder?sslmode=disable"
|
||||
|
||||
- name: Get experiments
|
||||
id: get_experiments
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
if [[ ${{ github.event_name }} == "workflow_dispatch" ]]; then
|
||||
experiments=${{ github.event.inputs.experiments }}
|
||||
else
|
||||
# extract experiments part
|
||||
extracted_experiments=$(echo "$COMMENT_BODY" | grep -oP '(?<=--experiments )[^ ]+')
|
||||
# Validate that the experiments is a comma-separated list of alphanumeric strings, "*", or "-"
|
||||
if [[ $extracted_experiments =~ ^[a-zA-Z0-9_*,\"-]+$ ]]; then
|
||||
experiments=$extracted_experiments
|
||||
else
|
||||
echo "Invalid input: $extracted_experiments"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
echo "experiments=$experiments" >> $GITHUB_OUTPUT
|
||||
env:
|
||||
COMMENT_BODY: ${{ github.event.comment.body || '' }}
|
||||
|
||||
- name: Create values.yaml
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
run: |
|
||||
cat <<EOF > pr-deploy-values.yaml
|
||||
coder:
|
||||
@@ -273,7 +332,7 @@ jobs:
|
||||
- name: "CODER_WILDCARD_ACCESS_URL"
|
||||
value: "*.${{ env.PR_DEPLOYMENT_ACCESS_URL }}"
|
||||
- name: "CODER_EXPERIMENTS"
|
||||
value: "*,${{ steps.get_experiments.outputs.experiments }}"
|
||||
value: "${{ github.event.inputs.experiments }}"
|
||||
- name: CODER_PG_CONNECTION_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
@@ -289,14 +348,27 @@ jobs:
|
||||
value: "coder"
|
||||
EOF
|
||||
|
||||
- name: Install Helm chart
|
||||
- name: Install/Upgrade Helm chart
|
||||
run: |
|
||||
helm upgrade --install "pr${{ env.PR_NUMBER }}" ./helm \
|
||||
--namespace "pr${{ env.PR_NUMBER }}" \
|
||||
--values ./pr-deploy-values.yaml \
|
||||
--force
|
||||
set -euxo pipefail
|
||||
if [[ ${{ github.event_name }} == "workflow_dispatch" ]]; then
|
||||
helm upgrade --install "pr${{ env.PR_NUMBER }}" ./helm \
|
||||
--namespace "pr${{ env.PR_NUMBER }}" \
|
||||
--values ./pr-deploy-values.yaml \
|
||||
--force
|
||||
else
|
||||
if [[ ${{ needs.get_info.outputs.BUILD }} == "true" ]]; then
|
||||
helm upgrade --install "pr${{ env.PR_NUMBER }}" ./helm \
|
||||
--namespace "pr${{ env.PR_NUMBER }}" \
|
||||
--reuse-values \
|
||||
--force
|
||||
else
|
||||
echo "Skipping helm upgrade, as there is no new image to deploy"
|
||||
fi
|
||||
fi
|
||||
|
||||
- name: Install coder-logstream-kube
|
||||
if: needs.get_info.outputs.NEW == 'true'
|
||||
run: |
|
||||
helm repo add coder-logstream-kube https://helm.coder.com/logstream-kube
|
||||
helm upgrade --install coder-logstream-kube coder-logstream-kube/coder-logstream-kube \
|
||||
@@ -304,6 +376,7 @@ jobs:
|
||||
--set url="https://pr${{ env.PR_NUMBER }}.${{ secrets.PR_DEPLOYMENTS_DOMAIN }}"
|
||||
|
||||
- name: Get Coder binary
|
||||
if: needs.get_info.outputs.NEW == 'true'
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
|
||||
@@ -329,6 +402,7 @@ jobs:
|
||||
mv "${DEST}" /usr/local/bin/coder
|
||||
|
||||
- name: Create first user, template and workspace
|
||||
if: needs.get_info.outputs.NEW == 'true'
|
||||
id: setup_deployment
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
@@ -364,6 +438,7 @@ jobs:
|
||||
coder stop test -y
|
||||
|
||||
- name: Send Slack notification
|
||||
if: needs.get_info.outputs.NEW == 'true'
|
||||
run: |
|
||||
curl -s -o /dev/null -X POST -H 'Content-type: application/json' \
|
||||
-d \
|
||||
@@ -382,23 +457,26 @@ jobs:
|
||||
|
||||
- name: Find Comment
|
||||
uses: peter-evans/find-comment@v2
|
||||
if: github.event_name == 'issue_comment'
|
||||
id: fc
|
||||
with:
|
||||
issue-number: ${{ env.PR_NUMBER }}
|
||||
comment-author: "github-actions[bot]"
|
||||
body-includes: This deployment will be deleted when the PR is closed
|
||||
body-includes: ":rocket:"
|
||||
direction: last
|
||||
|
||||
- name: Comment on PR
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
if: github.event_name == 'issue_comment'
|
||||
env:
|
||||
STATUS: ${{ needs.get_info.outputs.NEW == 'true' && 'Created' || 'Updated' }}
|
||||
with:
|
||||
issue-number: ${{ env.PR_NUMBER }}
|
||||
edit-mode: replace
|
||||
comment-id: ${{ steps.fc.outputs.comment-id }}
|
||||
body: |
|
||||
:heavy_check_mark: Deployed PR ${{ env.PR_NUMBER }} successfully.
|
||||
:rocket: Access the deployment link [here](https://${{ env.PR_DEPLOYMENT_ACCESS_URL }}).
|
||||
:warning: This deployment will be deleted when the PR is closed.
|
||||
---
|
||||
:heavy_check_mark: PR ${{ env.PR_NUMBER }} ${{ env.STATUS }} successfully.
|
||||
:rocket: Access the credentials [here](${{ secrets.PR_DEPLOYMENTS_SLACK_CHANNEL_URL }}).
|
||||
---
|
||||
cc: @${{ github.actor }}
|
||||
reactions: rocket
|
||||
reactions-edit-mode: replace
|
||||
|
||||
+12
-9
@@ -81,17 +81,20 @@ Use the following `make` commands and scripts in development:
|
||||
|
||||
### Deploying a PR
|
||||
|
||||
You can test your changes by creating a PR deployment. A PR deployment can be triggered in two ways:
|
||||
You can test your changes by creating a PR deployment. There are two ways to do this:
|
||||
|
||||
1. By commenting on the PR with `/deploy-pr`
|
||||
2. By running `./scripts/deploy-pr.sh`
|
||||
3. Available options
|
||||
- `-s` or `--skip-build`, the image will not be built again, and the last image will be used.
|
||||
- `-e EXPERIMENT1,EXPERIMENT2` or `--experiments EXPERIMENT1,EXPERIMENT2`, will enable the specified experiments.
|
||||
- `-n` or `--dry-run` will display the context without deployment. e.g., branch name and PR number, etc.
|
||||
- `-y` or `--yes`, will skip the CLI confirmation (only valid for the `./scripts/deploy-pr.sh`)
|
||||
1. By running `./scripts/deploy-pr.sh`
|
||||
2. By manually triggering the [`pr-deploy.yaml`](https://github.com/coder/coder/actions/workflows/pr-deploy.yaml) GitHub Action workflow
|
||||

|
||||
|
||||
> Note: all flags can be used with both `./scripts/deploy-pr.sh` and `/deploy-pr` comment on the PR.
|
||||
#### Available options
|
||||
|
||||
- `-s` or `--skip-build`, force prevents the build of the Docker image.(generally not needed as we are intelligently checking if the image needs to be built)
|
||||
- `-e EXPERIMENT1,EXPERIMENT2` or `--experiments EXPERIMENT1,EXPERIMENT2`, will enable the specified experiments. (defaults to `*`)
|
||||
- `-n` or `--dry-run` will display the context without deployment. e.g., branch name and PR number, etc.
|
||||
- `-y` or `--yes`, will skip the CLI confirmation prompt.
|
||||
|
||||
> Note: PR deployment will be re-deployed automatically when the PR is updated. It will use the last values automatically for redeployment.
|
||||
|
||||
> You need to be a member or collaborator of the of [coder](github.com/coder) GitHub organization to be able to deploy a PR.
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
Reference in New Issue
Block a user