diff --git a/.github/workflows/uffizzi-build.yml b/.github/workflows/uffizzi-build.yml index 0a5fad200..e6589430c 100644 --- a/.github/workflows/uffizzi-build.yml +++ b/.github/workflows/uffizzi-build.yml @@ -9,8 +9,7 @@ jobs: runs-on: ubuntu-latest if: ${{ github.event_name != 'pull_request' || github.event.action != 'closed' }} outputs: - compose-file-cache-key: ${{ steps.hash.outputs.hash }} - compose-file-cache-path: docker-compose.rendered.yml + tags: ${{ steps.meta.outputs.tags }} steps: - name: Checkout git repo uses: actions/checkout@v3 @@ -38,47 +37,49 @@ jobs: labels: ${{ steps.meta.outputs.labels }} file: ./uffizzi/Dockerfile cache-from: type=gha - cache-to: type=gha,mode=max - - uses: actions/checkout@v3 + cache-to: type=gha,mode=max + + render-compose-file: + name: Render Docker Compose File + # Pass output of this workflow to another triggered by `workflow_run` event. + runs-on: ubuntu-latest + needs: + - build-application + outputs: + compose-file-cache-key: ${{ steps.hash.outputs.hash }} + steps: + - name: Checkout git repo + uses: actions/checkout@v3 - name: Render Compose File run: | - APP_IMAGE=$(echo ${{ steps.meta.outputs.tags }}) + APP_IMAGE=$(echo ${{ needs.build-application.outputs.tags }}) export APP_IMAGE export UFFIZZI_URL=\$UFFIZZI_URL + # Render simple template from environment variables. envsubst '$APP_IMAGE' < ./uffizzi/docker-compose.uffizzi.yml > docker-compose.rendered.yml cat docker-compose.rendered.yml - - name: Hash Rendered Compose File - id: hash - run: echo "::set-output name=hash::$(md5sum docker-compose.rendered.yml | awk '{ print $1 }')" - - name: Cache Rendered Compose File - uses: actions/cache@v3 + - name: Upload Rendered Compose File as Artifact + uses: actions/upload-artifact@v3 with: + name: preview-spec path: docker-compose.rendered.yml - key: ${{ steps.hash.outputs.hash }} + retention-days: 2 + - name: Upload PR Event as Artifact + uses: actions/upload-artifact@v3 + with: + name: preview-spec + path: ${{ github.event_path }} + retention-days: 2 - deploy-uffizzi-preview: - name: Deploy preview - needs: build-application - uses: UffizziCloud/preview-action/.github/workflows/reusable.yaml@v2 - if: ${{ github.event_name == 'pull_request' && github.event.action != 'closed' }} - with: - compose-file-cache-key: ${{ needs.build-application.outputs.compose-file-cache-key }} - compose-file-cache-path: ${{ needs.build-application.outputs.compose-file-cache-path }} - server: https://app.uffizzi.com/ - permissions: - contents: read - pull-requests: write - id-token: write - - delete-uffizzi-preview: - name: Delete preview - uses: UffizziCloud/preview-action/.github/workflows/reusable.yaml@v2 - if: ${{ github.event_name == 'pull_request' && github.event.action == 'closed' }} - with: - compose-file-cache-key: '' - compose-file-cache-path: docker-compose.rendered.yml - server: https://app.uffizzi.com/ - permissions: - contents: read - pull-requests: write - id-token: write + delete-preview: + name: Call for Preview Deletion + runs-on: ubuntu-latest + if: ${{ 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: Upload PR Event as Artifact + uses: actions/upload-artifact@v3 + with: + name: preview-spec + path: ${{ github.event_path }} + retention-days: 2 diff --git a/.github/workflows/uffizzi-preview.yml b/.github/workflows/uffizzi-preview.yml new file mode 100644 index 000000000..88c5c96cd --- /dev/null +++ b/.github/workflows/uffizzi-preview.yml @@ -0,0 +1,89 @@ +name: Deploy Uffizzi Preview + +on: + workflow_run: + workflows: + - "Build PR Image" + types: + - completed + +jobs: + cache-compose-file: + name: Cache Compose File + runs-on: ubuntu-latest + if: ${{ github.event.workflow_run.conclusion == 'success' }} + 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]; + if (matchArtifact === undefined) { + throw TypeError('Build Artifact not found!'); + } + 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 -e '\nEOF' >> $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 + if: ${{ github.event.workflow_run.conclusion == 'success' }} + 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