From cf5015b85d5cc82ec8b168c9cd50dd6610fa64f6 Mon Sep 17 00:00:00 2001 From: Vibhav Bobade Date: Tue, 25 Oct 2022 03:20:16 +0530 Subject: [PATCH] chore: previews for every PR release using Uffizzi add github workflows to take the prebuilt docker image for the PR to create a preview deployment on Uffizzi. Comment will be posted to every PR on a successful deployment. --- .github/uffizzi/docker-compose.uffizzi.yml | 24 ++++++ .github/workflows/release-pr.yml | 71 +++++++++++++++-- .github/workflows/uffizzi-preview.yml | 88 ++++++++++++++++++++++ 3 files changed, 176 insertions(+), 7 deletions(-) create mode 100644 .github/uffizzi/docker-compose.uffizzi.yml create mode 100644 .github/workflows/uffizzi-preview.yml diff --git a/.github/uffizzi/docker-compose.uffizzi.yml b/.github/uffizzi/docker-compose.uffizzi.yml new file mode 100644 index 0000000000..eb33d7d3e9 --- /dev/null +++ b/.github/uffizzi/docker-compose.uffizzi.yml @@ -0,0 +1,24 @@ +version: '3' + +x-uffizzi: + ingress: + service: nocodb + port: 8080 + +services: + root_db: + image: postgres + restart: always + environment: + POSTGRES_PASSWORD: password + POSTGRES_USER: postgres + POSTGRES_DB: root_db + nocodb: + image: "${NOCODB_IMAGE}" + ports: + - "8080:8080" + restart: always + environment: + NC_DB: "pg://localhost:5432?u=postgres&p=password&d=root_db" + NC_ADMIN_EMAIL: admin@nocodb.com + NC_ADMIN_PASSWORD: password \ No newline at end of file diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml index d104e79089..80c4780c31 100644 --- a/.github/workflows/release-pr.yml +++ b/.github/workflows/release-pr.yml @@ -6,7 +6,8 @@ on: # reopened: closed pull request is reopened # synchronize: commit(s) pushed to the pull request # ready_for_review: non PR release - types: [opened, reopened, synchronize, ready_for_review] + # closed: pull request is closed, used to delete uffizzi previews + types: [opened, reopened, synchronize, ready_for_review, closed] paths: - "packages/nocodb-sdk/**" - "packages/nc-gui/**" @@ -20,7 +21,7 @@ concurrency: jobs: # enrich tag for pr release set-tag: - if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' && github.event.pull_request.draft == false && github.base_ref == 'develop' }} + if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' && github.event.pull_request.draft == false && github.base_ref == 'develop' && github.event.action != 'closed' }} runs-on: 'ubuntu-latest' steps: - name: set-tag @@ -47,7 +48,7 @@ jobs: # Build, install, publish frontend and backend to npm release-npm: - if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' && github.event.pull_request.draft == false && github.base_ref == 'develop' }} + if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' && github.event.pull_request.draft == false && github.base_ref == 'develop' && github.event.action != 'closed' }} needs: [set-tag] uses: ./.github/workflows/release-npm.yml with: @@ -58,7 +59,7 @@ jobs: # Build docker image and push to docker hub release-docker: - if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' && github.event.pull_request.draft == false && github.base_ref == 'develop' }} + if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' && github.event.pull_request.draft == false && github.base_ref == 'develop' && github.event.action != 'closed' }} needs: [release-npm, set-tag] uses: ./.github/workflows/release-docker.yml with: @@ -72,7 +73,7 @@ jobs: # Build executables and publish to GitHub release-executables: - if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' && github.event.pull_request.draft == false && github.base_ref == 'develop' }} + if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' && github.event.pull_request.draft == false && github.base_ref == 'develop' && github.event.action != 'closed' }} needs: [set-tag, release-npm] uses: ./.github/workflows/release-timely-executables.yml with: @@ -82,7 +83,7 @@ jobs: # Add a comment for PR docker build leave-comment: - if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' && github.event.pull_request.draft == false && github.base_ref == 'develop' }} + if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' && github.event.pull_request.draft == false && github.base_ref == 'develop' && github.event.action != 'closed' }} runs-on: 'ubuntu-latest' needs: [release-docker, set-tag] steps: @@ -94,9 +95,45 @@ jobs: docker run -d -p 8888:8080 nocodb/nocodb-timely:${{ needs.set-tag.outputs.current_version }}-${{ needs.set-tag.outputs.target_tag }} ``` + # Create a preview for the pull request + preview-pull-request: + name: "Trigger Uffizzi Preview" + if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' && github.event.pull_request.draft == false && github.base_ref == 'develop' && github.event.action != 'closed' }} + runs-on: 'ubuntu-latest' + needs: [release-docker, set-tag] + outputs: + compose-file-cache-key: ${{ env.COMPOSE_FILE_HASH }} + steps: + - name: Checkout git repo + uses: actions/checkout@v3 + - name: Render Compose File + run: | + NOCODB_IMAGE=nocodb/nocodb-timely:${{ needs.set-tag.outputs.current_version }}-${{ needs.set-tag.outputs.target_tag }} + export NOCODB_IMAGE + # Render simple template from environment variables. + envsubst < .github/uffizzi/docker-compose.uffizzi.yml > docker-compose.rendered.yml + cat docker-compose.rendered.yml + - name: Upload Rendered Compose File as Artifact + uses: actions/upload-artifact@v3 + with: + name: preview-spec + path: docker-compose.rendered.yml + retention-days: 2 + - name: Serialize PR Event to File + run: | + cat << EOF > event.json + ${{ toJSON(github.event) }} + EOF + - name: Upload PR Event as Artifact + uses: actions/upload-artifact@v3 + with: + name: preview-spec + path: event.json + retention-days: 2 + # Add a comment for PR executable build leave-executable-comment: - if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' && github.event.pull_request.draft == false && github.base_ref == 'develop' }} + if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' && github.event.pull_request.draft == false && github.base_ref == 'develop' && github.event.action != 'closed' }} runs-on: 'ubuntu-latest' needs: [release-executables, set-tag] steps: @@ -129,3 +166,23 @@ jobs: ``` For executables visit [here](https://github.com/nocodb/nocodb-timely/releases/tag/${{ needs.set-tag.outputs.current_version }}-${{ needs.set-tag.outputs.target_tag }}) + + # delete the uffizzi preview created off of this PR + delete-uffizzi-preview: + name: Call for Preview Deletion + runs-on: ubuntu-latest + if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' && github.event.pull_request.draft == false && github.base_ref == 'develop' && github.event.action == 'closed' }} + steps: + # If this PR is closing, we will not render a compose file nor pass it to the next workflow. + - name: Serialize PR Event to File + run: | + cat << EOF > event.json + ${{ toJSON(github.event) }} + + EOF + - name: Upload PR Event as Artifact + uses: actions/upload-artifact@v3 + with: + name: preview-spec + path: event.json + retention-days: 2 \ No newline at end of file diff --git a/.github/workflows/uffizzi-preview.yml b/.github/workflows/uffizzi-preview.yml new file mode 100644 index 0000000000..470acaa0e0 --- /dev/null +++ b/.github/workflows/uffizzi-preview.yml @@ -0,0 +1,88 @@ +name: Deploy Uffizzi Preview + +on: + workflow_run: + workflows: + - "PR Release" + types: + - completed + +jobs: + cache-compose-file: + name: Cache Compose File + runs-on: ubuntu-latest + outputs: + compose-file-cache-key: ${{ env.COMPOSE_FILE_HASH }} + pr-number: ${{ env.PR_NUMBER }} + steps: + - name: 'Download artifacts' + # Fetch output (zip archive) from the workflow run that triggered this workflow. + uses: actions/github-script@v6 + with: + script: | + let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: context.payload.workflow_run.id, + }); + let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => { + return artifact.name == "preview-spec" + })[0]; + let download = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: matchArtifact.id, + archive_format: 'zip', + }); + let fs = require('fs'); + fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/preview-spec.zip`, Buffer.from(download.data)); + + - name: 'Unzip artifact' + run: unzip preview-spec.zip + + - name: Read Event into ENV + run: | + echo 'EVENT_JSON<> $GITHUB_ENV + cat event.json >> $GITHUB_ENV + echo 'EOF' >> $GITHUB_ENV + + - name: Hash Rendered Compose File + id: hash + # If the previous workflow was triggered by a PR close event, we will not have a compose file artifact. + if: ${{ fromJSON(env.EVENT_JSON).action != 'closed' }} + run: echo "COMPOSE_FILE_HASH=$(md5sum docker-compose.rendered.yml | awk '{ print $1 }')" >> $GITHUB_ENV + + - name: Cache Rendered Compose File + if: ${{ fromJSON(env.EVENT_JSON).action != 'closed' }} + uses: actions/cache@v3 + with: + path: docker-compose.rendered.yml + key: ${{ env.COMPOSE_FILE_HASH }} + + - name: Read PR Number From Event Object + id: pr + run: echo "PR_NUMBER=${{ fromJSON(env.EVENT_JSON).number }}" >> $GITHUB_ENV + + - name: DEBUG - Print Job Outputs + if: ${{ runner.debug }} + run: | + echo "PR number: ${{ env.PR_NUMBER }}" + echo "Compose file hash: ${{ env.COMPOSE_FILE_HASH }}" + cat event.json + + deploy-uffizzi-preview: + name: Use Remote Workflow to Preview on Uffizzi + needs: + - cache-compose-file + uses: UffizziCloud/preview-action/.github/workflows/reusable.yaml@v2 + with: + # If this workflow was triggered by a PR close event, cache-key will be an empty string + # and this reusable workflow will delete the preview deployment. + compose-file-cache-key: ${{ needs.cache-compose-file.outputs.compose-file-cache-key }} + compose-file-cache-path: docker-compose.rendered.yml + server: https://app.uffizzi.com + pr-number: ${{ needs.cache-compose-file.outputs.pr-number }} + permissions: + contents: read + pull-requests: write + id-token: write \ No newline at end of file