Skip to content

Deploy PR

Deploy PR #1294

Workflow file for this run

name: Deploy PR
on:
workflow_run:
workflows: [build-pr]
types: [completed]
jobs:
deploy-pr:
runs-on: ubuntu-latest
if: |
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.conclusion == 'success'
permissions:
deployments: write
steps:
- name: Download build artifact
uses: actions/github-script@d556feaca394842dc55e4734bf3bb9f685482fa0
with:
script: |
let artifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: ${{ github.event.workflow_run.id }},
});
artifacts = artifacts.data.artifacts.filter((artifact) => {
return artifact.name == "build"
});
if (artifacts.length <= 0) {
throw new Error("No artifact found.");
}
const matchArtifact = artifacts[0];
const download = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: matchArtifact.id,
archive_format: 'zip',
});
const fs = require('fs');
fs.writeFileSync('${{github.workspace}}/artifact.zip', Buffer.from(download.data));
- name: Unzip artifact
run: unzip artifact.zip
- name: Get PR number
id: get-pr-number
uses: actions/github-script@d556feaca394842dc55e4734bf3bb9f685482fa0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require("fs");
const prId = parseInt(fs.readFileSync("./pr.txt", "utf8"), 10);
if (isNaN(prId) || prId <= 0) {
throw new Error("Invalid PR id.");
}
return prId;
# Normally github automatically displays a deployment status for workflows
# that are related to a specific commit. But since this workflow is triggered
# by the 'workflow_run' event, the commit sha for this run is the sha from
# the 'main' branch rather than the commit from the PR.
# So we'll manually create a deployment status, this also allows us to
# set the environment_url so that github displays a button that leads you
# directly to the deployed page.
- name: Create deployment for status
id: create-deployment
uses: actions/github-script@d556feaca394842dc55e4734bf3bb9f685482fa0
env:
BUILD_COMMIT_SHA: ${{ github.event.workflow_run.head_sha }}
PR_ID: ${{ steps.get-pr-number.outputs.result }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const {BUILD_COMMIT_SHA, PR_ID} = process.env;
const {data: deploymentData} = await github.request("POST /repos/{owner}/{repo}/deployments", {
owner: context.repo.owner,
repo: context.repo.repo,
ref: BUILD_COMMIT_SHA,
environment: "PR preview",
auto_merge: false,
transient_environment: true,
task: "deploy_pr:" + PR_ID,
required_contexts: ["build / build"],
});
return deploymentData.id;
- name: Update deployment status with in progress
if: ${{ failure() }}
uses: actions/github-script@d556feaca394842dc55e4734bf3bb9f685482fa0
env:
DEPLOYMENT_ID: ${{ steps.create-deployment.outputs.result }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const {DEPLOYMENT_ID} = process.env;
await github.request("POST /repos/{owner}/{repo}/deployments/{deploymentId}/statuses", {
owner: context.repo.owner,
repo: context.repo.repo,
deploymentId: DEPLOYMENT_ID,
state: "in_progress",
});
- name: Deploy files
env:
PR_DEPLOY_TOKEN: ${{ secrets.PR_DEPLOY_TOKEN }}
PR_ID: ${{ steps.get-pr-number.outputs.result }}
run: |
curl -X POST --fail -H "Authorization: DeployToken $PR_DEPLOY_TOKEN" -H "Content-Type: application/x-tar" --data-binary @build_files.tar "https://deploy.renda.studio/pr?id=$PR_ID"
- name: Update deployment status success
uses: actions/github-script@d556feaca394842dc55e4734bf3bb9f685482fa0
env:
DEPLOYMENT_ID: ${{ steps.create-deployment.outputs.result }}
PR_ID: ${{ steps.get-pr-number.outputs.result }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const {DEPLOYMENT_ID, PR_ID} = process.env;
await github.request("POST /repos/{owner}/{repo}/deployments/{deploymentId}/statuses", {
owner: context.repo.owner,
repo: context.repo.repo,
deploymentId: DEPLOYMENT_ID,
state: "success",
environment_url: `https://pr-${ PR_ID }.renda.studio`
});
// Delete previous deployments except for the one we just created.
const iterator = github.paginate.iterator("GET /repos/{owner}/{repo}/deployments", {
owner: context.repo.owner,
repo: context.repo.repo,
task: "deploy_pr:" + PR_ID,
});
const allDeployments = [];
for await (const {data: deployments} of iterator) {
for (const deployment of deployments) {
allDeployments.push(deployment);
}
}
for (const deployment of allDeployments) {
const deploymentId = deployment.id;
if (deploymentId == DEPLOYMENT_ID) continue;
console.log(`Deleting ${deploymentId}`);
await github.request("POST /repos/{owner}/{repo}/deployments/{deploymentId}/statuses", {
owner: context.repo.owner,
repo: context.repo.repo,
deploymentId,
state: "inactive",
});
await github.request("DELETE /repos/{owner}/{repo}/deployments/{deploymentId}", {
owner: context.repo.owner,
repo: context.repo.repo,
deploymentId,
});
}
- name: Update deployment status failure
if: ${{ failure() }}
uses: actions/github-script@d556feaca394842dc55e4734bf3bb9f685482fa0
env:
DEPLOYMENT_ID: ${{ steps.create-deployment.outputs.result }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const {DEPLOYMENT_ID} = process.env;
await github.request("POST /repos/{owner}/{repo}/deployments/{deploymentId}/statuses", {
owner: context.repo.owner,
repo: context.repo.repo,
deploymentId: DEPLOYMENT_ID,
state: "failure",
});