Skip to content

Integrate Uffizzi #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions .github/workflows/uffizzi-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
name: Build PR Image
on:
pull_request:
types: [opened, synchronize, reopened, closed, review_requested]

jobs:
build-parse-dashboard:
name: Build and push `Parse-Dashboard`
runs-on: ubuntu-latest
outputs:
tags: ${{ steps.meta.outputs.tags }}
if: ${{ github.event.action != 'closed' }}
steps:
- name: Checkout git repo
uses: actions/checkout@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Generate UUID image name
id: uuid
run: echo "UUID_WORKER=$(uuidgen)" >> $GITHUB_ENV

- name: Docker metadata
id: meta
uses: docker/metadata-action@v4
with:
images: registry.uffizzi.com/${{ env.UUID_WORKER }}
tags: |
type=raw,value=60d

- name: Build and Push Image to registry.uffizzi.com - Uffizzi's ephemeral Registry
uses: docker/build-push-action@v3
with:
context: ./
file: Dockerfile
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
push: true
cache-from: type=gha
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-parse-dashboard
outputs:
compose-file-cache-key: ${{ steps.hash.outputs.hash }}
steps:
- name: Checkout git repo
uses: actions/checkout@v3
- name: Render Compose File
run: |
PARSE_DASHBOARD_IMAGE=${{ needs.build-parse-dashboard.outputs.tags }}
export PARSE_DASHBOARD_IMAGE
export UFFIZZI_URL=\$UFFIZZI_URL
# Render simple template from environment variables.
envsubst < 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

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: 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
88 changes: 88 additions & 0 deletions .github/workflows/uffizzi-preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
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.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<<EOF' >> $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 "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.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.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
69 changes: 69 additions & 0 deletions docker-compose.uffizzi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
version: '3'

# uffizzi integration
x-uffizzi:
ingress:
service: nginx
port: 8081

services:

postgres:
image: postgres
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=password
- POSTGRES_DB=postgres
ports:
- "5432:5432"
deploy:
resources:
limits:
memory: 1000M
volumes:
- postgres_data:/var/lib/postgresql

parse:
image: parseplatform/parse-server:latest
environment:
- PARSE_SERVER_APPLICATION_ID=parse
- PARSE_SERVER_MASTER_KEY=parse@master123!
- PARSE_SERVER_DATABASE_URI=postgresql://postgres:password@localhost:5432/postgres
- PARSE_SERVER_MOUNT_PATH=/parse
- PORT=1337
ports:
- '1337:1337'
deploy:
resources:
limits:
memory: 1000M
dashboard:
image: "${PARSE_DASHBOARD_IMAGE}"
ports:
- "4040:4040"
environment:
- PARSE_DASHBOARD_MASTER_KEY=parse@master123!
- PARSE_DASHBOARD_APP_ID=parse
- PARSE_DASHBOARD_APP_NAME=MyParseApp
- PARSE_DASHBOARD_USER_ID=admin
- PARSE_DASHBOARD_USER_PASSWORD=password
- MOUNT_PATH=/dashboard
- PARSE_DASHBOARD_ALLOW_INSECURE_HTTP=1
entrypoint: /bin/sh
command:
- "-c"
- "PARSE_DASHBOARD_SERVER_URL=$$UFFIZZI_URL/parse node Parse-Dashboard/index.js"
#- PARSE_DASHBOARD_COOKIE_SESSION_SECRET=AB8849B6-D725-4A75-AA73-AB7103F0363F
deploy:
resources:
limits:
memory: 1000M

nginx:
image: nginx:alpine
volumes:
- ./nginx-uffizzi:/etc/nginx
- ./nginx-uffizzi/html:/usr/share/nginx/html

volumes:
postgres_data:
20 changes: 20 additions & 0 deletions nginx-uffizzi/html/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!doctype html>

<html>

<head>

<title>Parse Dashboard Preview</title>

</head>

<body>

<h1>Endpoints</h1>

<a href="/dashboard/"><b>Click to Visit Parse Dashboard</b></a>


</body>

</html>
33 changes: 33 additions & 0 deletions nginx-uffizzi/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
events {
worker_connections 1024; #default
}
http {
server {
listen 8081;

location / {
root /usr/share/nginx/html;
index index.html index.htm;
}

location /dashboard {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:4040/dashboard/;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_redirect off;
}

location /parse {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
keepalive_requests 10;
keepalive_timeout 75s;
proxy_pass http://localhost:1337/parse/;
proxy_http_version 1.1;
}
}
}