1- # This action will trigger when a PR is commentted containing /review -pr by a member of the org .
1+ # This action will trigger when a PR is commented on with `/deploy -pr` or when the workflow is manually triggered .
22name : Deploy PR
33on :
44 issue_comment :
88 pr_number :
99 description : " PR number"
1010 required : true
11+ skip_build :
12+ description : " Skip build job"
13+ required : false
14+ default : false
1115
1216env :
1317 REPO : ghcr.io/coder/coder-preview
6266
6367 - name : Comment on PR
6468 id : comment_id
69+ if : github.event_name == 'issue_comment'
6570 uses : peter-evans/create-or-update-comment@v3
6671 with :
6772 issue-number : ${{ steps.pr_info.outputs.PR_NUMBER }}
7277
7378 build :
7479 needs : pr_commented
80+ # Skips the build job if the workflow was triggered by a workflow_dispatch event and the skip_build input is set to true
81+ # or if the workflow was triggered by an issue_comment event and the comment body contains --skip-build
82+ 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)
7583 runs-on : ${{ github.repository_owner == 'coder' && 'buildjet-8vcpu-ubuntu-2204' || 'ubuntu-latest' }}
7684 env :
7785 DOCKER_CLI_EXPERIMENTAL : " enabled"
@@ -119,16 +127,32 @@ jobs:
119127
120128 deploy :
121129 needs : [build, pr_commented]
122- if : needs.build.result == 'success'
130+ # Run deploy job only if build job was successful or skipped
131+ if : always() && (needs.build.result == 'success' || needs.build.result == 'skipped') && needs.pr_commented.result == 'success'
123132 runs-on : " ubuntu-latest"
124133 env :
125134 CODER_IMAGE_TAG : ${{ needs.pr_commented.outputs.CODER_IMAGE_TAG }}
126135 PR_NUMBER : ${{ needs.pr_commented.outputs.PR_NUMBER }}
127136 PR_TITLE : ${{ needs.pr_commented.outputs.PR_TITLE }}
128137 PR_URL : ${{ needs.pr_commented.outputs.PR_URL }}
138+ PR_BRANCH : ${{ needs.pr_commented.outputs.PR_BRANCH }}
139+ PR_DEPLOYMENT_ACCESS_URL : " https://pr${{ needs.pr_commented.outputs.PR_NUMBER }}.${{ secrets.PR_DEPLOYMENTS_DOMAIN }}"
129140 steps :
141+ - name : Check if image exists
142+ run : |
143+ set -euxo pipefail
144+ foundTag=$(curl -fsSL https://github.com/coder/coder/pkgs/container/coder-preview | grep -o ${{ env.CODER_IMAGE_TAG }} | head -n 1)
145+ if [ -z "$foundTag" ]; then
146+ echo "Image not found"
147+ echo "${{ env.CODER_IMAGE_TAG }} not found in ghcr.io/coder/coder-preview"
148+ echo "Please remove --skip-build from the comment or ./scripts/deploy-pr.sh"
149+ exit 1
150+ fi
151+
130152 - name : Checkout
131153 uses : actions/checkout@v3
154+ with :
155+ ref : ${{ env.PR_BRANCH }}
132156
133157 - name : Set up kubeconfig
134158 run : |
@@ -157,6 +181,7 @@ jobs:
157181 spec:
158182 tls:
159183 - hosts:
184+ - "${{ secrets.PR_DEPLOYMENTS_DOMAIN }}"
160185 - "*.${{ secrets.PR_DEPLOYMENTS_DOMAIN }}"
161186 secretName: pr${{ env.PR_NUMBER }}-tls
162187 rules:
@@ -173,32 +198,56 @@ jobs:
173198 EOF
174199 kubectl apply -f ingress.yaml
175200
201+ - name : Set up PostgreSQL database
202+ run : |
203+ helm repo add bitnami https://charts.bitnami.com/bitnami
204+ helm install coder-db bitnami/postgresql \
205+ --namespace pr${{ env.PR_NUMBER }} \
206+ --set auth.username=coder \
207+ --set auth.password=coder \
208+ --set auth.database=coder \
209+ --set persistence.size=10Gi
210+ kubectl create secret generic coder-db-url -n pr${{ env.PR_NUMBER }} \
211+ --from-literal=url="postgres://coder:[email protected] ${{ env.PR_NUMBER }}.svc.cluster.local:5432/coder?sslmode=disable" 212+
213+ - name : Create values.yaml
214+ run : |
215+ cat <<EOF > pr-deploy-values.yaml
216+ coder:
217+ image:
218+ repo: ${{ env.REPO }}
219+ tag: pr${{ env.PR_NUMBER }}
220+ pullPolicy: Always
221+ service:
222+ type: ClusterIP
223+ env:
224+ - name: "CODER_ACCESS_URL"
225+ value: "https://pr${{ env.PR_NUMBER }}.${{ secrets.PR_DEPLOYMENTS_DOMAIN }}"
226+ - name: "CODER_WILDCARD_ACCESS_URL"
227+ value: "*--pr${{ env.PR_NUMBER }}.${{ secrets.PR_DEPLOYMENTS_DOMAIN }}"
228+ - name: "CODER_EXPERIMENTS"
229+ value: "*"
230+ - name: CODER_PG_CONNECTION_URL
231+ valueFrom:
232+ secretKeyRef:
233+ name: coder-db-url
234+ key: url
235+ - name: "CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS"
236+ value: "true"
237+ - name: "CODER_OAUTH2_GITHUB_CLIENT_ID"
238+ value: "${{ secrets.PR_DEPLOYMENTS_GITHUB_OAUTH_CLIENT_ID }}"
239+ - name: "CODER_OAUTH2_GITHUB_CLIENT_SECRET"
240+ value: "${{ secrets.PR_DEPLOYMENTS_GITHUB_OAUTH_CLIENT_SECRET }}"
241+ - name: "CODER_OAUTH2_GITHUB_ALLOWED_ORGS"
242+ value: "coder"
243+ EOF
244+
176245 - name : Install Helm chart
177246 run : |
178- helm upgrade --install pr${{ env.PR_NUMBER }} ./helm \
247+ helm upgrade --install " pr${{ env.PR_NUMBER }}" ./helm \
179248 --namespace "pr${{ env.PR_NUMBER }}" \
180- --set coder.image.repo=${{ env.REPO }} \
181- --set coder.image.tag=pr${{ env.PR_NUMBER }} \
182- --set coder.service.type=ClusterIP \
183- --set coder.serviceAccount.enableDeployments=true \
184- --set coder.env[0].name=CODER_ACCESS_URL \
185- --set coder.env[0].value="https://pr${{ env.PR_NUMBER }}.${{ secrets.PR_DEPLOYMENTS_DOMAIN }}" \
186- --set coder.env[1].name=CODER_WILDCARD_ACCESS_URL \
187- --set coder.env[1].value="*--pr${{ env.PR_NUMBER }}.${{ secrets.PR_DEPLOYMENTS_DOMAIN }}" \
188- --set coder.env[2].name=CODER_EXPERIMENTS \
189- --set coder.env[2].value="*" \
249+ --values ./pr-deploy-values.yaml \
190250 --force
191- # Uncomment this when https://github.com/coder/coder/issues/8714 is resolved
192- # --set coder.env[3].name=CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS \
193- # --set coder.env[3].value=true \
194- # --set coder.env[4].name=CODER_OAUTH2_GITHUB_CLIENT_ID \
195- # --set coder.env[4].value=${{ secrets.PR_DEPLOYMENTS_GITHUB_OAUTH_CLIENT_ID }} \
196- # --set coder.env[5].name=CODER_OAUTH2_GITHUB_CLIENT_SECRET \
197- # --set coder.env[5].value=${{ secrets.PR_DEPLOYMENTS_GITHUB_OAUTH_CLIENT_SECRET }} \
198- # --set coder.env[6].name=CODER_OAUTH2_GITHUB_ALLOWED_ORGS \
199- # --set coder.env[6].value=coder \
200- # --set coder.env[7].name=CODER_OAUTH2_GITHUB_REDIRECT_URI \
201- # --set coder.env[7].value="https://pr${{ env.PR_NUMBER }}.${{ secrets.PR_DEPLOYMENTS_DOMAIN }}/gitauth/github/callback
202251
203252 - name : Install coder-logstream-kube
204253 run : |
@@ -207,28 +256,95 @@ jobs:
207256 --namespace "pr${{ env.PR_NUMBER }}" \
208257 --set url="https://pr${{ env.PR_NUMBER }}.${{ secrets.PR_DEPLOYMENTS_DOMAIN }}"
209258
259+ - name : Get Coder binary
260+ run : |
261+ set -euxo pipefail
262+
263+ DEST="${HOME}/coder"
264+ URL="${{ env.PR_DEPLOYMENT_ACCESS_URL }}/bin/coder-linux-amd64"
265+
266+ mkdir -p "$(dirname ${DEST})"
267+
268+ COUNT=0
269+ until $(curl --output /dev/null --silent --head --fail "$URL"); do
270+ printf '.'
271+ sleep 5
272+ COUNT=$((COUNT+1))
273+ if [ $COUNT -ge 60 ]; then
274+ echo "Timed out waiting for URL to be available"
275+ exit 1
276+ fi
277+ done
278+
279+ curl -fsSL "$URL" -o "${DEST}"
280+ chmod +x "${DEST}"
281+ "${DEST}" version
282+
283+ - name : Create first user, template and workspace
284+ id : setup_deployment
285+ run : |
286+ set -euxo pipefail
287+
288+ # Create first user
289+
290+ # create a masked random password 12 characters long
291+ password=$(openssl rand -base64 16 | tr -d "=+/" | cut -c1-12)
292+
293+ # add mask so that the password is not printed to the logs
294+ echo "::add-mask::$password"
295+ echo "password=$password" >> $GITHUB_OUTPUT
296+
297+ /home/runner/coder login \
298+ --first-user-username pr${{ env.PR_NUMBER }} \
299+ --first-user-email ${{ env.PR_NUMBER }}@coder.com \
300+ --first-user-password $password \
301+ --first-user-trial \
302+ --use-token-as-session \
303+ ${{ env.PR_DEPLOYMENT_ACCESS_URL }}
304+
305+ # Create template
306+ /home/runner/coder templates init --id kubernetes && cd ./kubernetes/ && /home/runner/coder templates create -y --variable namespace=pr${{ env.PR_NUMBER }}
307+
308+ # Create workspace
309+ cat <<EOF > workspace.yaml
310+ cpu: "2"
311+ memory: "4"
312+ home_disk_size: "2"
313+ EOF
314+
315+ /home/runner/coder create --template="kubernetes" pr${{ env.PR_NUMBER }} --rich-parameter-file ./workspace.yaml -y
316+ /home/runner/coder stop pr${{ env.PR_NUMBER }} -y
317+
210318 - name : Send Slack notification
211319 run : |
212320 curl -s -o /dev/null -X POST -H 'Content-type: application/json' \
213- -d '{
214- "pr_number": "'"${{ env.PR_NUMBER }}"'",
215- "pr_url": "'"${{ env.PR_URL }}"'",
216- "pr_title": "'"${{ env.PR_TITLE }}"'",
217- "pr_access_url": "'"${{ env.PR_DEPLOYMENT_ACCESS_URL }}"'" }' ${{ secrets.PR_DEPLOYMENTS_SLACK_WEBHOOK }}
321+ -d \
322+ '{
323+ "pr_number": "'"${{ env.PR_NUMBER }}"'",
324+ "pr_url": "'"${{ env.PR_URL }}"'",
325+ "pr_title": "'"${{ env.PR_TITLE }}"'",
326+ "pr_access_url": "'"${{ env.PR_DEPLOYMENT_ACCESS_URL }}"'",
327+ "pr_username": "'"pr${{ env.PR_NUMBER }}"'",
328+ "pr_email": "'"${{ env.PR_NUMBER }}@coder.com"'",
329+ "pr_password": "'"${{ steps.setup_deployment.outputs.password }}"'",
330+ "pr_actor": "'"${{ github.actor }}"'"
331+ }' \
332+ ${{ secrets.PR_DEPLOYMENTS_SLACK_WEBHOOK }}
218333 echo "Slack notification sent"
219- env :
220- PR_DEPLOYMENT_ACCESS_URL : " https://pr${{ env.PR_NUMBER }}.${{ secrets.PR_DEPLOYMENTS_DOMAIN }}"
221334
222335 - name : Find Comment
223336 uses : peter-evans/find-comment@v2
337+ if : github.event_name == 'issue_comment'
224338 id : fc
225339 with :
226340 issue-number : ${{ env.PR_NUMBER }}
227341 comment-author : " github-actions[bot]"
228342 body-includes : This deployment will be deleted when the PR is closed
343+ direction : last
229344
230345 - name : Comment on PR
231346 uses : peter-evans/create-or-update-comment@v3
347+ if : github.event_name == 'issue_comment'
232348 with :
233349 issue-number : ${{ env.PR_NUMBER }}
234350 edit-mode : replace
@@ -238,6 +354,3 @@ jobs:
238354 :rocket: Access the deployment link [here](${{ env.PR_DEPLOYMENT_ACCESS_URL }}).
239355 :warning: This deployment will be deleted when the PR is closed.
240356 reactions : rocket
241-
242- env :
243- PR_DEPLOYMENT_ACCESS_URL : " https://pr${{ env.PR_NUMBER }}.${{ secrets.PR_DEPLOYMENTS_DOMAIN }}"
0 commit comments