Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 23 additions & 6 deletions .github/workflows/_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,21 @@ on:
description: Name of the built artifact for deployment.
required: true
type: string
artifact_run_id:
description: ID of the workflow run that uploaded the artifact. Defaults to the current run.
required: false
type: string
default: ''
pr_number:
description: Number of the pull request to comment on with a link to the preview.
required: false
type: number
default: -1
pr_head_sha:
description: Commit that the pull request preview was built from.
required: false
type: string
default: ''
s3_prefix:
description: AWS S3 prefix where to store the build.
required: true
Expand All @@ -26,8 +41,6 @@ on:
required: true
type: string

concurrency: deploy-${{ github.ref }}

jobs:
deploy-to-cloudfront:
runs-on: ubuntu-latest
Expand All @@ -36,13 +49,14 @@ jobs:
deployment: true
url: ${{ inputs.environment_url }}
permissions:
actions: read
id-token: write
pull-requests: write
steps:
- name: Create app token
uses: actions/create-github-app-token@v3
id: app-token
if: ${{ inputs.environment_name == 'preview' }}
if: ${{ inputs.pr_number > 0 }}
with:
client-id: ${{ vars.THEOPLAYER_BOT_APP_ID }}
private-key: ${{ secrets.THEOPLAYER_BOT_PRIVATE_KEY }}
Expand All @@ -52,6 +66,8 @@ jobs:
with:
name: ${{ inputs.artifact_name }}
path: ${{ github.workspace }}/${{ inputs.artifact_name }}
run-id: ${{ inputs.artifact_run_id || github.run_id }}
github-token: ${{ github.token }}

- name: Configure AWS credentials ☁️
uses: aws-actions/configure-aws-credentials@v6
Expand Down Expand Up @@ -81,17 +97,18 @@ jobs:

- name: Get deployment timestamp 🕰️
id: timestamp
if: ${{ inputs.environment_name == 'preview' }}
if: ${{ inputs.pr_number > 0 }}
run: echo "time=$(date -u '+%Y-%m-%d %H:%M %Z')" >> "$GITHUB_OUTPUT"

- name: Add comment to Pull Request with link to preview 🕸️
uses: marocchino/sticky-pull-request-comment@v3
if: ${{ inputs.environment_name == 'preview' }}
if: ${{ inputs.pr_number > 0 }}
with:
header: pr-preview
number: ${{ inputs.pr_number }}
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
message: |
Documentation preview
:---:
| :rocket: View preview at <br> ${{ inputs.environment_url }} <br><br>
| <h6>Deployed from commit ${{ github.event.pull_request.head.sha }} at ${{ steps.timestamp.outputs.time }}.</h6>
| <h6>Deployed from commit ${{ inputs.pr_head_sha }} at ${{ steps.timestamp.outputs.time }}.</h6>
2 changes: 0 additions & 2 deletions .github/workflows/_undeploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ on:
required: true
type: string

concurrency: deploy-${{ github.ref }}

jobs:
undeploy-from-cloudfront:
runs-on: ubuntu-latest
Expand Down
80 changes: 80 additions & 0 deletions .github/workflows/pull-request-preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: 'Pull request preview'

# Deploys the build artifact from "On Pull Requests" to the preview environment.
# This workflow runs in the context of the main branch, so it has access to
# secrets and the AWS OIDC token, even for pull requests from forks.
# It must never check out or run code from the pull request.
# See https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/
on:
workflow_run:
workflows: ['On Pull Requests']
types:
- completed
pull_request_target:
types:
- closed

jobs:
pull-request:
name: pull-request
if: >-
github.event_name == 'workflow_run'
&& github.event.workflow_run.event == 'pull_request'
&& github.event.workflow_run.conclusion == 'success'
&& github.event.workflow_run.actor.login != 'dependabot[bot]'
runs-on: ubuntu-latest
permissions:
pull-requests: read
outputs:
number: ${{ steps.pr.outputs.number }}
head_sha: ${{ github.event.workflow_run.head_sha }}
is_fork: ${{ github.event.workflow_run.head_repository.full_name != github.repository }}
steps:
- name: Find pull request for commit 🔍
id: pr
# The workflow_run event does not list pull requests from forks,
# so look up the open pull request whose head is exactly this commit.
run: |
number=$(gh api "repos/${GITHUB_REPOSITORY}/commits/${HEAD_SHA}/pulls" \
--jq "[.[] | select(.state == \"open\" and .head.sha == \"${HEAD_SHA}\" and .head.repo.full_name == \"${HEAD_REPO}\")] | first | .number")
if [[ -z "$number" || "$number" == "null" ]]; then
echo "No open pull request found with head ${HEAD_REPO}@${HEAD_SHA}, skipping preview."
exit 1
fi
echo "number=${number}" >> "$GITHUB_OUTPUT"
env:
GH_TOKEN: ${{ github.token }}
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
HEAD_REPO: ${{ github.event.workflow_run.head_repository.full_name }}

deploy:
name: deploy
needs: [pull-request]
concurrency: preview-pr-${{ needs.pull-request.outputs.number }}
uses: ./.github/workflows/_deploy.yml
secrets: inherit
permissions:
actions: read
id-token: write
pull-requests: write
with:
# Deployments from forks use a separate environment, so that they can require approval.
environment_name: ${{ needs.pull-request.outputs.is_fork == 'true' && 'preview-fork' || 'preview' }}
environment_url: '${{ vars.PREVIEW_CLOUDFRONT_URL }}/pr-${{ needs.pull-request.outputs.number }}/'
artifact_name: dist.zip
artifact_run_id: ${{ github.event.workflow_run.id }}
pr_number: ${{ fromJSON(needs.pull-request.outputs.number) }}
pr_head_sha: ${{ needs.pull-request.outputs.head_sha }}
s3_prefix: 'pr-${{ needs.pull-request.outputs.number }}'
cf_invalidate_path: '/pr-${{ needs.pull-request.outputs.number }}*'

undeploy:
name: undeploy
if: ${{ github.event_name == 'pull_request_target' && github.triggering_actor != 'dependabot[bot]' }}
concurrency: preview-pr-${{ github.event.number }}
uses: ./.github/workflows/_undeploy.yml
secrets: inherit
with:
environment_name: preview
s3_prefix: 'pr-${{ github.event.number }}'
cf_invalidate_path: '/pr-${{ github.event.number }}*'
33 changes: 5 additions & 28 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
@@ -1,56 +1,33 @@
name: 'On Pull Requests'

# This workflow runs on pull requests from forks too, so it has no access to
# secrets, environment variables or the AWS OIDC token. Deployment happens in
# pull-request-preview.yml, which never runs code from the pull request.
on:
pull_request:
types:
- opened
- reopened
- synchronize
- ready_for_review
- closed

jobs:
lint:
name: lint
if: ${{ github.event.action != 'closed' }}
uses: ./.github/workflows/_lint.yml
secrets: inherit

build:
name: build
if: ${{ github.event.action != 'closed' }}
uses: ./.github/workflows/_build.yml
with:
environment_name: preview
# Preview URLs look like this: https://[storage-url]/pr-[number]/
docusaurus_url: ${{ vars.PREVIEW_CLOUDFRONT_URL }}
# The URL is hardcoded because `vars` are not available to pull requests from forks.
docusaurus_url: 'https://docs-preview.optiview.dolby.com'
docusaurus_base_url: '/pr-${{ github.event.number }}/'
# Prevent PR previews from being indexed by search engines
docusaurus_no_index: 1
# Add an announcement at the top to indicate if this is a preview
docusaurus_pr_number: ${{ github.event.number }}
docusaurus_pr_url: ${{ github.event.pull_request.html_url }}

deploy:
name: deploy
needs: [build]
# Do not run on PRs from Dependabot, since they should not need it.
if: ${{ github.event.action != 'closed' && github.triggering_actor != 'dependabot[bot]' }}
uses: ./.github/workflows/_deploy.yml
secrets: inherit
with:
environment_name: preview
environment_url: '${{ vars.PREVIEW_CLOUDFRONT_URL }}/pr-${{ github.event.number }}/'
artifact_name: ${{ needs.build.outputs.artifact_name }}
s3_prefix: 'pr-${{ github.event.number }}'
cf_invalidate_path: '/pr-${{ github.event.number }}*'

undeploy:
name: undeploy
if: ${{ github.event.action == 'closed' && github.triggering_actor != 'dependabot[bot]' }}
uses: ./.github/workflows/_undeploy.yml
secrets: inherit
with:
environment_name: preview
s3_prefix: 'pr-${{ github.event.number }}'
cf_invalidate_path: '/pr-${{ github.event.number }}*'
Loading