From 93ef759a257a1aebf98b9a54fc6698b4732b05f7 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Tue, 8 Dec 2020 13:49:22 +0100 Subject: Add: [Actions] preview workflow, where PRs can be reviewed in the browser When a developer attaches the "preview" label, a build is created and published on https://preview.openttd.org/. After that, new pushes to the PR are automatically build (as long as the "preview" label exists). If a non-developer attaches the "preview" label, it will be removed. --- .github/workflows/preview_build.yml | 133 ++++++++++++++++++++++++++++++++++++ .github/workflows/preview_label.yml | 66 ++++++++++++++++++ .github/workflows/preview_push.yml | 66 ++++++++++++++++++ 3 files changed, 265 insertions(+) create mode 100644 .github/workflows/preview_build.yml create mode 100644 .github/workflows/preview_label.yml create mode 100644 .github/workflows/preview_push.yml (limited to '.github/workflows') diff --git a/.github/workflows/preview_build.yml b/.github/workflows/preview_build.yml new file mode 100644 index 000000000..9aea890bc --- /dev/null +++ b/.github/workflows/preview_build.yml @@ -0,0 +1,133 @@ +name: Preview build + +on: + repository_dispatch: + types: + - Preview* + +jobs: + preview: + name: Build preview + + runs-on: ubuntu-20.04 + container: + # If you change this version, change the number in the cache step too. + image: emscripten/emsdk:2.0.10 + # uid=1001(runner) gid=121(docker) + options: -u 1001:121 + + steps: + - name: Update deployment status to in progress + uses: octokit/request-action@v2.x + with: + route: POST /repos/{owner}/{repo}/deployments/{deployment_id}/statuses + mediaType: | + previews: + - ant-man + - flash + owner: ${{ github.event.repository.owner.login }} + repo: ${{ github.event.repository.name }} + deployment_id: ${{ github.event.client_payload.deployment_id }} + state: in_progress + env: + GITHUB_TOKEN: ${{ secrets.PREVIEW_GITHUB_TOKEN }} + + - name: Checkout + uses: actions/checkout@v2 + with: + ref: ${{ github.event.client_payload.sha }} + + - name: Name branch + run: | + name=$(echo "${{ github.event.client_payload.folder }}") + git checkout -b ${name} + + - name: Setup cache + uses: actions/cache@v2 + with: + path: /emsdk/upstream/emscripten/cache + key: 2.0.10-${{ runner.os }} + + - name: Build (host tools) + run: | + mkdir build-host + cd build-host + + echo "::group::CMake" + cmake .. -DOPTION_TOOLS_ONLY=ON + echo "::endgroup::" + + echo "::group::Build" + echo "Running on $(nproc) cores" + make -j$(nproc) tools + echo "::endgroup::" + + - name: Install GCC problem matcher + uses: ammaraskar/gcc-problem-matcher@master + + - name: Build + run: | + mkdir build + cd build + + echo "::group::CMake" + emcmake cmake .. \ + -DHOST_BINARY_DIR=../build-host \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + # EOF + echo "::endgroup::" + + echo "::group::Build" + echo "Running on $(nproc) cores" + emmake make -j$(nproc) + echo "::endgroup::" + + - name: Publish preview + run: | + # setuptools is missing in this Docker image, which breaks installing + # awscli. So we need to do this in two steps to recover sanity. + pip3 install setuptools + pip3 install awscli + + ~/.local/bin/aws s3 cp --only-show-errors build/openttd.data s3://${{ secrets.PREVIEW_S3_BUCKET }}/${{ github.event.client_payload.folder }}/ + ~/.local/bin/aws s3 cp --only-show-errors build/openttd.html s3://${{ secrets.PREVIEW_S3_BUCKET }}/${{ github.event.client_payload.folder }}/ + ~/.local/bin/aws s3 cp --only-show-errors build/openttd.js s3://${{ secrets.PREVIEW_S3_BUCKET }}/${{ github.event.client_payload.folder }}/ + ~/.local/bin/aws s3 cp --only-show-errors build/openttd.wasm s3://${{ secrets.PREVIEW_S3_BUCKET }}/${{ github.event.client_payload.folder }}/ + + # Invalidate the cache of the CloudFront distribution + ~/.local/bin/aws cloudfront create-invalidation --distribution-id ${{ secrets.PREVIEW_CF_DISTRIBUTION_ID }} --paths "/${{ github.event.client_payload.folder }}/*" + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + + - name: Update deployment status to success + uses: octokit/request-action@v2.x + with: + route: POST /repos/{owner}/{repo}/deployments/{deployment_id}/statuses + mediaType: | + previews: + - ant-man + - flash + owner: ${{ github.event.repository.owner.login }} + repo: ${{ github.event.repository.name }} + deployment_id: ${{ github.event.client_payload.deployment_id }} + state: success + environment_url: https://preview.openttd.org/${{ github.event.client_payload.folder }}/ + env: + GITHUB_TOKEN: ${{ secrets.PREVIEW_GITHUB_TOKEN }} + + - if: failure() + name: Update deployment status to failure + uses: octokit/request-action@v2.x + with: + route: POST /repos/{owner}/{repo}/deployments/{deployment_id}/statuses + mediaType: | + previews: + - ant-man + - flash + owner: ${{ github.event.repository.owner.login }} + repo: ${{ github.event.repository.name }} + deployment_id: ${{ github.event.client_payload.deployment_id }} + state: failure + env: + GITHUB_TOKEN: ${{ secrets.PREVIEW_GITHUB_TOKEN }} diff --git a/.github/workflows/preview_label.yml b/.github/workflows/preview_label.yml new file mode 100644 index 000000000..6b3e17ea1 --- /dev/null +++ b/.github/workflows/preview_label.yml @@ -0,0 +1,66 @@ +name: Preview label + +on: + pull_request_target: + types: + - labeled + +env: + TEAM_CORE_DEVELOPER: core-developers + +jobs: + check_preview_label: + name: Check for preview label + if: github.event.action == 'labeled' && github.event.label.name == 'preview' + + runs-on: ubuntu-20.04 + + steps: + - name: Check if label was added by core developer + id: core_developer + continue-on-error: true + uses: octokit/request-action@v2.x + with: + route: GET /orgs/OpenTTD/teams/${{ env.TEAM_CORE_DEVELOPER }}/memberships/${{ github.event.sender.login }} + env: + GITHUB_TOKEN: ${{ secrets.PREVIEW_GITHUB_TOKEN }} + + - if: steps.core_developer.outcome == 'failure' + name: Remove preview label if not core developer + uses: octokit/request-action@v2.x + with: + route: DELETE /repos/{owner}/{repo}/issues/{issue_number}/labels/preview + owner: ${{ github.event.repository.owner.login }} + repo: ${{ github.event.repository.name }} + issue_number: ${{ github.event.number }} + env: + GITHUB_TOKEN: ${{ secrets.PREVIEW_GITHUB_TOKEN }} + + - if: steps.core_developer.outcome == 'success' + name: Create deployment + id: deployment + uses: octokit/request-action@v2.x + with: + route: POST /repos/{owner}/{repo}/deployments + mediaType: | + previews: + - ant-man + - flash + owner: ${{ github.event.repository.owner.login }} + repo: ${{ github.event.repository.name }} + ref: ${{ github.event.pull_request.head.sha }} + task: deploy:preview + auto_merge: false + required_contexts: "[]" + environment: preview-pr-${{ github.event.number }} + description: "Preview for Pull Request #${{ github.event.number }}" + env: + GITHUB_TOKEN: ${{ secrets.PREVIEW_GITHUB_TOKEN }} + + - if: steps.core_developer.outcome == 'success' + name: Trigger 'preview build' + uses: peter-evans/repository-dispatch@v1 + with: + token: ${{ secrets.PREVIEW_GITHUB_TOKEN }} + event-type: "Preview build #${{ github.event.number }}" + client-payload: '{"folder": "pr${{ github.event.number }}", "sha": "${{ github.event.pull_request.head.sha }}", "deployment_id": "${{ fromJson(steps.deployment.outputs.data).id }}"}' diff --git a/.github/workflows/preview_push.yml b/.github/workflows/preview_push.yml new file mode 100644 index 000000000..cb68c8f6c --- /dev/null +++ b/.github/workflows/preview_push.yml @@ -0,0 +1,66 @@ +name: Preview push + +on: + pull_request_target: + types: + - synchronize + +jobs: + check_new_preview: + name: Check preview needs update + + runs-on: ubuntu-20.04 + + steps: + - name: Check if earlier preview exists + id: earlier_preview + uses: octokit/request-action@v2.x + with: + route: GET /repos/{owner}/{repo}/deployments + owner: ${{ github.event.repository.owner.login }} + repo: ${{ github.event.repository.name }} + environment: preview-pr-${{ github.event.number }} + per_page: 1 + env: + GITHUB_TOKEN: ${{ secrets.PREVIEW_GITHUB_TOKEN }} + + - if: toJson(fromJson(steps.earlier_preview.outputs.data)) != '[]' + name: Check for preview label + id: preview_label + uses: octokit/request-action@v2.x + with: + route: GET /repos/{owner}/{repo}/issues/{issue_number}/labels + owner: ${{ github.event.repository.owner.login }} + repo: ${{ github.event.repository.name }} + issue_number: ${{ github.event.number }} + env: + GITHUB_TOKEN: ${{ secrets.PREVIEW_GITHUB_TOKEN }} + + - if: toJson(fromJson(steps.earlier_preview.outputs.data)) != '[]' && contains(fromJson(steps.preview_label.outputs.data).*.name, 'preview') + name: Create deployment + id: deployment + uses: octokit/request-action@v2.x + with: + route: POST /repos/{owner}/{repo}/deployments + mediaType: | + previews: + - ant-man + - flash + owner: ${{ github.event.repository.owner.login }} + repo: ${{ github.event.repository.name }} + ref: ${{ github.event.pull_request.head.sha }} + task: deploy:preview + auto_merge: false + required_contexts: "[]" + environment: preview-pr-${{ github.event.number }} + description: "Preview for Pull Request #${{ github.event.number }}" + env: + GITHUB_TOKEN: ${{ secrets.PREVIEW_GITHUB_TOKEN }} + + - if: toJson(fromJson(steps.earlier_preview.outputs.data)) != '[]' && contains(fromJson(steps.preview_label.outputs.data).*.name, 'preview') + name: Trigger 'preview build' + uses: peter-evans/repository-dispatch@v1 + with: + token: ${{ secrets.PREVIEW_GITHUB_TOKEN }} + event-type: "Preview build #${{ github.event.number }}" + client-payload: '{"folder": "pr${{ github.event.number }}", "sha": "${{ github.event.pull_request.head.sha }}", "deployment_id": "${{ fromJson(steps.deployment.outputs.data).id }}"}' -- cgit v1.2.3-70-g09d2