Skip to content

Latest commit

 

History

History
331 lines (247 loc) · 11.4 KB

deploy-preview.md

File metadata and controls

331 lines (247 loc) · 11.4 KB

Deploy preview site for Pull Requests

With this workflows you can deploy preview site for Pull Requests by Prow-like slash command /ok-to-preview sha=<commit SHA>. Preview sites are served from Static website hosting in Azure Storage. The workflow also comments to the pull request an example of the commands for preview. Its now even easier to check build results in reviewing process before publish the changes.

Prerequisites

Create GitHub App

  1. Go to Settings for your GitHub organization.

    https://github.com/organizations/{YOUR ORG}/settings/profile

  2. Select Developer settings > GitHub Apps.

  3. Select New GitHub App.

  4. Enter GitHub App name and Homepage URL.

  5. Remove check from Webhook Active.

  6. Set repository permissions.

    • Contents: Read & write
    • Metadata: Read-only
    • Pull requests: Read-only
    • Secrets: Read & write
  7. Select Only on this account. Select Create GitHub App.

  8. The AppID appeares in the General page of the GitHub App.

  9. Move to Private keys section. Select Generate a private key.

Install GitHub App to your organization

  1. Go to Install App. Select Install.

  2. Enable Only select repositories option and select your blog repository. Select Install.

Configure the GitHub secrets

  1. Go to Secrets settings for your blog repository.

    https://github.com/{YOUR ORG}/blog/settings/secrets/actions

  2. Select New repository secret and add following secrets:

    • APP_ID: App ID of created GitHub App
    • PRIVATE_KEY: Private key of created GitHub App
    • AZURE_STORAGE_CONNECTION_STRING: Connection string for Azure Blob Storage

Workflows

You need to store following YAMLs in the .github/workflows directory of your blog repository.

1. pull-request-target.yml: workflow posting comment and cleaning up preview site for closed pull request.

# File: {your-blog-repo}/.github/workflows/pull-request-target.yml

name: pull-request-target

on:
  pull_request_target:
    types: [opened, reopened, closed]

jobs:
  pr-comment:
    runs-on: ubuntu-latest
    if:
      github.event_name == 'pull_request_target' &&
      (github.event.action == 'opened' || github.event.action == 'reopened')
    steps:
    - name: pr-comment
      uses: cssjpn/blog-gh-actions/pr-comment@v1
      with:
        token: ${{ secrets.GITHUB_TOKEN }}

  delete-preview:
    runs-on: ubuntu-latest
    if:
      github.event_name == 'pull_request_target' && github.event.action == 'closed'
    steps:
    - name: Delete preview site
      uses: cssjpn/blog-gh-actions/delete-preview@v1
      with:
        token: ${{ secrets.GITHUB_TOKEN }}
        azure-storage-connection-string: ${{ secrets.AZURE_STORAGE_CONNECTION_STRING }}

2. ok-to-preview.yml: workflow dispatching deploy-preview workflow by /ok-to-preview command

# File: {your-blog-repo}/.github/workflows/pull-request-target.yml

name: ok-to-preview

on:
  issue_comment:
    types: [created]

jobs:
  ok-to-preview:
    runs-on: ubuntu-latest
    if:
      github.event.issue.pull_request && github.event.issue.state == 'open'

    steps:
    - name: Generate token
      id: generate_token
      uses: tibdex/github-app-token@v1
      with:
        app_id: ${{ secrets.APP_ID }}
        private_key: ${{ secrets.PRIVATE_KEY }}

    - name: Slash Command Dispatch
      uses: peter-evans/slash-command-dispatch@v2
      env:
        TOKEN: ${{ steps.generate_token.outputs.token }}
      with:
        token: ${{ env.TOKEN }}
        reaction-token: ${{ secrets.GITHUB_TOKEN }}
        issue-type: pull-request
        commands: ok-to-preview
        permission: write

3. deploy-preview.yml: workflow deploying preview site

You need to replace preview-base-url value to your Static Website Hosting URL.

# File: {your-blog-repo}/.github/workflows/deploy-preview.yml

name: deploy-preview

on:
  repository_dispatch:
    types: [ok-to-preview-command]

jobs:
  deploy-preview:
    runs-on: ubuntu-latest
    if:
      github.event_name == 'repository_dispatch' &&
      github.event.client_payload.slash_command.args.named.sha != '' &&
      contains(github.event.client_payload.pull_request.head.sha, github.event.client_payload.slash_command.args.named.sha)
    steps:
    - name: PR checkout
      uses: actions/checkout@v2
      with:
        ref: 'refs/pull/${{ github.event.client_payload.pull_request.number }}/merge'
        submodules: true

    - name: Deploy preview site
      uses: cssjpn/blog-gh-actions/deploy-preview@v1
      with:
        token: ${{ secrets.GITHUB_TOKEN }}
        azure-storage-connection-string: ${{ secrets.AZURE_STORAGE_CONNECTION_STRING }}
        preview-base-url: "https://{{ Your Static Web URL }}.z11.web.core.windows.net/"

Note: GitHub automatically creates a GITHUB_TOKEN secret to use in your workflow. Authentication in a workflow - GitHub Docs

4. update-credential.yml and pull-request-target.yml: workflows for enable auto deploy task.

If you would like to deploy preview site automatically, please update pull-request-target.yml as below.

deploy-preview-if-pr-owner-is-linked-account job call internal api to validate PR owner is Microsoft linked account or not. If PR is created by Microsoft linked account, then Deploy preview site step will be invoked.

# File: {your-blog-repo}/.github/workflows/pull-request-target.yml

name: pull-request-target

on:
  pull_request_target:
    types: [opened, reopened, edited, closed] # added edited type.

jobs:
  pr-comment:
    runs-on: ubuntu-latest
    if:
      github.event_name == 'pull_request_target' &&
      (github.event.action == 'opened' || github.event.action == 'reopened')
    steps:
    - name: pr-comment
      uses: cssjpn/blog-gh-actions/pr-comment@v1
      with:
        token: ${{ secrets.GITHUB_TOKEN }}

  # If you want to deploy preview site automatically
  deploy-preview-if-pr-owner-is-linked-account:
    runs-on: ubuntu-latest
    if:
      github.event_name == 'pull_request_target' &&
      (github.event.action == 'opened' || github.event.action == 'reopened' || github.event.action == 'edited')
    steps:
      - name: check linked account
        # skip checking if pr is created by repository owner
        if: github.event.pull_request.head.repo.owner.login != github.event.repository.owner.login
        id: check_linked_account
        uses: cssjpn/blog-gh-actions/check-linked-account@v1
        with:
          token: ${{ secrets.JPCSSBLOG_DEV_TOKEN }}
          allowExternalUser: 'allow'

      # Checks-out after passed the check
      - uses: actions/checkout@v2
        if:
          steps.check_linked_account.outputs.isLinked == 'true' || 
          github.event.pull_request.head.repo.owner.login == github.event.repository.owner.login
        with:
          ref: 'refs/pull/${{ github.event.number }}/merge'
          submodules: true

      - name: Deploy preview site
        if:
          steps.check_linked_account.outputs.isLinked == 'true' || 
          github.event.pull_request.head.repo.owner.login == github.event.repository.owner.login
        uses: cssjpn/blog-gh-actions/deploy-preview@v1
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          azure-storage-connection-string: ${{ secrets.AZURE_STORAGE_CONNECTION_STRING }}
          preview-base-url: "https://{{ Your Static Web URL }}.z5.web.core.windows.net/" # need to update url.
          branch-name: ${{ github.event.pull_request.head.label }}
          pr-url: ${{ github.event.pull_request.html_url }}
          repo-owner: ${{ github.event.repository.owner.login }}
          repo-name: ${{ github.event.repository.name }}

  delete-preview:
    runs-on: ubuntu-latest
    if:
      github.event_name == 'pull_request_target' && github.event.action == 'closed'
    steps:
    - name: Delete preview site
      uses: cssjpn/blog-gh-actions/delete-preview@v1
      with:
        token: ${{ secrets.GITHUB_TOKEN }}
        azure-storage-connection-string: ${{ secrets.AZURE_STORAGE_CONNECTION_STRING }}

You need to get access token before run check-linked-account action. The following action help you getting and storing access token to GitHub secrets using GitHub ID Token.

Make sure your GitHub Apps have write permission to GitHub Secrets.

# File: {your-blog-repo}/.github/workflows/update-credential.yml

name: get jpcssblogdev token

on:
  schedule:
    - cron: '0 0 1,15 * *'
  workflow_dispatch:

permissions:
  id-token: write
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@v2

      - name: Get JPCSSBlogDev Token
        id: jpcssblogdev
        uses: cssjpn/blog-gh-actions/jpcssblogdev-token@v1

      - name: Generate GitHub token for writing secrets
        id: generate_token
        uses: tibdex/github-app-token@v1
        with:
          app_id: ${{ secrets.APP_ID }}
          private_key: ${{ secrets.PRIVATE_KEY }}

      - name: Store a token to repository Secrets
        env:
          TOKEN: ${{ steps.jpcssblogdev.outputs.token }}
          GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
          REPOSITORY: ${{ github.event.repository.full_name }}
        run: |
          gh secret set JPCSSBLOG_DEV_TOKEN --body "$TOKEN" -R "$REPOSITORY"  

Once you have added a workflow, you will need to run it manually only the first time. After that, secret will be updated on the 1st and 15th of every month.

Actions

Credits