Skip to content

Deploy preview environment #1104

Deploy preview environment

Deploy preview environment #1104

name: Deploy preview environment
on:
workflow_run:
workflows: [CI]
types: [completed]
workflow_dispatch:
inputs:
pr:
required: true
type: string
description: PR number
pull_request_target:
types: [labeled]
permissions:
contents: read
pull-requests: write
actions: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Get PR/workflow run info
id: get-info
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
console.dir(context, { depth: null });
let pr;
let workflowRun;
let isLabel = false;
switch (context.eventName) {
case "workflow_dispatch":
console.log("Workflow dispatch event");
pr = (await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: +context.payload.inputs.pr,
})).data;
break;
case "pull_request_target":
console.log("Pull request target event");
pr = context.payload.pull_request;
break;
case "workflow_run":
console.log("Workflow run event");
workflowRun = context.payload.workflow_run;
pr = workflowRun.pull_requests[0];
if (pr) {
console.log("PR found in workflow run");
// Reload the PR to get the labels.
pr = (await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number,
})).data;
} else {
const q = `is:pr is:open repo:${context.repo.owner}/${context.repo.repo} sha:${workflowRun.head_sha}`;
console.log(`PR not found in workflow run, searching for it with ${q}`);
// PRs sent from forks do not get the pull_requests field set.
// https://github.com/orgs/community/discussions/25220
const response = await github.rest.search.issuesAndPullRequests({ q });
if (response.data.items.length > 0) {
pr = response.data.items[0];
}
}
}
if (!pr) {
console.log("Could not find PR");
return null;
}
console.log(`Found PR ${pr.html_url}`);
console.dir(pr, { depth: null });
if (pr.state !== "open") {
console.log(`PR ${pr.number} is not open`);
return null;
}
if (!pr.labels.some((label) => label.name === "deploy-preview")) {
console.log(`PR ${pr.number} does not have the deploy-preview label`);
return null;
}
if (!workflowRun) {
console.log(`No workflow run found in event, searching for it with ${pr.head.sha}`);
try {
workflowRun = (await github.rest.actions.listWorkflowRuns({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: "CI.yml",
head_sha: pr.head.sha,
per_page: 1,
})).data.workflow_runs[0];
} catch (e) {
console.log(e);
}
}
if (!workflowRun) {
console.log(`Could not find workflow run for PR ${pr.number}`);
return null;
}
console.log(`Found workflow run ${workflowRun.html_url}`);
console.dir(workflowRun, { depth: null });
try {
const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: "microsoft",
repo: "TypeScript-Website",
run_id: workflowRun.id,
});
console.dir(artifacts, { depth: null });
if (!artifacts.data.artifacts.some(x => x.name === "site")) {
console.log("No artifact found in workflow run");
return null;
}
} catch (e) {
console.log(e);
return null;
}
const result = { pr: pr.number, runId: workflowRun.id };
console.log(result);
return result;
- name: Download site build from PR
if: ${{ steps.get-info.outputs.result != 'null' }}
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: site
path: site
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ fromJson(steps.get-info.outputs.result).runId }}
- name: Deploy
id: deploy
if: ${{ steps.get-info.outputs.result != 'null' }}
uses: Azure/static-web-apps-deploy@v1
with:
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_PREVIEW }}
# Unsetting the repo token so we can control commenting ourselves.
# repo_token: ${{ secrets.GITHUB_TOKEN }}
action: "upload"
app_location: "site"
skip_app_build: true
production_branch: v2
deployment_environment: ${{ fromJson(steps.get-info.outputs.result).pr }}
- name: Comment on PR
if: ${{ steps.get-info.outputs.result != 'null' }}
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
env:
PR_NUMBER: ${{ fromJson(steps.get-info.outputs.result).pr }}
SITE_URL: ${{ steps.deploy.outputs.static_web_app_url }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const prefix = "Azure Static Web Apps: Your stage site is ready!";
const comments = await github.paginate(github.rest.issues.listComments, {
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: +process.env.PR_NUMBER,
per_page: 100,
});
for (const comment of comments) {
if (comment.user?.login === "github-actions[bot]" && comment.body?.startsWith(prefix)) {
console.log(`Deleting comment ${comment.id}`);
await github.rest.issues.deleteComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: comment.id,
});
}
}
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: +process.env.PR_NUMBER,
body: `${prefix} Visit it here: ${process.env.SITE_URL}`
});