petitviolet blog

    Manage new entry using GitHub Actions

    2020-03-18

    GoogleAppEngineGitHub Actions

    The previous entry describes how to deploy static sites through GitHub Actions. As the next step, this entry is going to show how to manage new entries, and also how to publish entries based on schedules.

    Deploy preview versions triggered by pull requests

    Deploying preview versions for every pull_request is a well-known good practice. To archive this, it needs a couple of things. First, deploy the new version not to the production environment, but to another environment like development/staging. Second, send notifications including a URL for the preview version to notify where I can see it.

    This blog is running on GAE. Since it provides service versioning, it's easy to get the first stuff done. Most of the YAML is duplicated with the previous entry, so it shows only the different steps.

    on:
      pull_request:
        types: [opened]
    
    name: deploy preview app
    
    jobs:
      run:
        runs-on: ubuntu-latest
    
        # prepare, build package
    
        - name: setup gcloud environment
          uses: GoogleCloudPlatform/github-actions@0.1.2
          with:
            version: '281.0.0'
            service_account_email: ${{ secrets.GCP_SERVICE_ACCOUNT_EMAIL }}
            service_account_key: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY }}
    
        - name: deploy
          run: |
            gcloud app deploy \
                --project $(GAE_PRODUCTION) \
                --version "preview-pr-${{ github.event.number }}" \
                --no-promote \
                --quiet \
                ./app.yaml
    

    The most important part is the last step. Using gcloud app deploy with --no-promote and --version options. --no-promote indicates this deployment will not accept traffics from users as the production version. To deploy to production, use --promote instead. Another option, --version is an identifier of this deployment. Additionally, the string "preview-pr-${{ github.event.number }}" passed to --version option contains the number of the pull request, so that it should be unique by each pull request. As the result, the preview URL looks like https://preview-pr-100-dot-<service>-dot-<project>.appspot.com.

    You can find the manner of GAE URL here. https://cloud.google.com/appengine/docs/standard/go/how-requests-are-routed?hl=ja#requests_and_domains.

    Send notification to the pull request

    After the success of deploying a preview version, the next step is to notify the preview site URL where the preview is available. Preview URLs can be constructed from the GAE service version, so the rest problem is the way to notify.

    To make it simple here, post a comment on the pull request. You can find documents here. https://developer.github.com/v3/issues/comments/#create-a-comment

    post_comment:
      runs-on: ubuntu-latest
      needs: run
    
      steps:
        - uses: actions/checkout@v2
    
        - name: post
          run: |
            remote_url="https://preview-pr-100-dot-<service>-dot-<project>.appspot.com"
            curl \
              -X POST \
              -H "Content-Type: application/json" \
              -H "Accept: application/vnd.github.v3+json" \
              -H "Authorization: token $GITHUB_TOKEN" \
              --data "{ \"body\": \"CI succeeded! <br /> The preview URL is: <a href='${remote_url}'>${remote_url}</a>\" }" \
              ${{ github.event.pull_request.comments_url }}
          env:
            GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    

    As it uses the GITHUB_TOKEN associated with GitHub Actions, the comment appears like posted by a bot.

    https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token

    In case you want to pretend as you posted comments instead of the bot, you can replace GITHUB_TOKEN with your own generated token. For example, set GITHUB_ACTION_TOKEN in secrets and use it as GITHUB_TOKEN: ${{ secrets.GITHUB_ACTION_TOKEN }}.

    As the result of this action, PR comment from bot will be like:

    img