Skip to content
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
35 changes: 35 additions & 0 deletions .github/workflows/cleanup-pr-preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Cleanup PR Preview

on:
pull_request:
types: [closed]

jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- name: Setup kubectl
uses: azure/setup-kubectl@v2.0

- name: Set Kubernetes context
uses: Azure/k8s-set-context@v2
with:
kubeconfig: ${{ secrets.KUBE_CONFIG }}

- name: Delete preview resources
run: |
PR_NUMBER="${{ github.event.pull_request.number }}"

echo "Cleaning up preview resources for PR #${PR_NUMBER}..."

# Delete deployment, service, and ingress
kubectl delete deployment sparrow-web-pr-${PR_NUMBER} \
--namespace=sparrow-preview --ignore-not-found=true

kubectl delete service sparrow-web-pr-${PR_NUMBER} \
--namespace=sparrow-preview --ignore-not-found=true

kubectl delete ingress sparrow-web-pr-${PR_NUMBER} \
--namespace=sparrow-preview --ignore-not-found=true

echo "✅ Preview resources cleaned up for PR #${PR_NUMBER}"
32 changes: 26 additions & 6 deletions .github/workflows/pr-build-trigger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ jobs:

const branch = pr.data.head.ref;
const sha = pr.data.head.sha;
const repo = pr.data.base.repo.full_name;
const repo = pr.data.head.repo.full_name;
const pr_number = pr.data.number;

console.log(`Branch : ${branch}`);
Expand Down Expand Up @@ -176,14 +176,19 @@ jobs:
owner: context.repo.owner,
repo: context.repo.repo,
body: [
"🚀 **Build triggered** for branch `${{ needs.validate.outputs.branch }}` from `${{ needs.validate.outputs.repo }}`.",
"🚀 **Builds triggered** for branch `${{ needs.validate.outputs.branch }}` from `${{ needs.validate.outputs.repo }}`.",
"",
"⏳ Build is currently in progress. You will receive a status update here once it completes."
"| Build | Type |",
"|-------|------|",
"| Desktop App (Win/Mac) | Binary |",
"| Webapp Preview | Docker + K8s |",
"",
"⏳ Builds are currently in progress. You will receive status updates here once they complete."
].join("\n")
});

# Step 3 — Dispatch the PR build workflow with the source branch and repository
- name: Trigger PR Build Workflow
- name: Trigger Desktop PR Build Workflow
id: dispatch
uses: benc-uk/workflow-dispatch@v1
with:
Expand All @@ -192,6 +197,16 @@ jobs:
inputs: '{"branch": "${{ needs.validate.outputs.branch }}", "repository": "${{ needs.validate.outputs.repo }}", "pr_number": "${{ needs.validate.outputs.pr_number }}"}'
token: ${{ secrets.PAT_TOKEN }}

# Step 3b — Dispatch the Webapp Preview workflow
- name: Trigger Webapp Preview Workflow
id: dispatch_webapp
uses: benc-uk/workflow-dispatch@v1
with:
workflow: sparrow-webapp-pr-preview.yml
ref: main
inputs: '{"branch": "${{ needs.validate.outputs.branch }}", "repository": "${{ needs.validate.outputs.repo }}", "pr_number": "${{ needs.validate.outputs.pr_number }}"}'
token: ${{ secrets.PAT_TOKEN }}

# Step 4 — Set commit status to success after dispatch
# (Scenario 4 — build feedback posted to PR)
- name: Set commit status — success
Expand Down Expand Up @@ -219,9 +234,14 @@ jobs:
owner: context.repo.owner,
repo: context.repo.repo,
body: [
"✅ **Build dispatched successfully** for branch `${{ needs.validate.outputs.branch }}` from `${{ needs.validate.outputs.repo }}`.",
"✅ **Builds dispatched successfully** for branch `${{ needs.validate.outputs.branch }}` from `${{ needs.validate.outputs.repo }}`.",
"",
"| Build | Status |",
"|-------|--------|",
"| Desktop App | 🚀 Dispatched |",
"| Webapp Preview | 🚀 Dispatched |",
"",
"You can monitor the build progress in the [Actions tab](https://github.com/${{ github.repository }}/actions)."
"You can monitor progress in the [Actions tab](https://github.com/${{ github.repository }}/actions)."
].join("\n")
});

Expand Down
20 changes: 16 additions & 4 deletions .github/workflows/sparrow-app-pr-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ jobs:
}
$msiFileName = $msiFile.Name
$msiUrl = "https://sparrow-release-assests-dev.s3.us-west-1.amazonaws.com/windows/$msiFileName"
$webappPreviewUrl = "https://pr-${{ inputs.pr_number }}.preview.sparrowapp.dev"
$buildDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$body = @{
"type" = "message"
Expand All @@ -359,7 +360,7 @@ jobs:
}
@{
"type" = "TextBlock"
"text" = "Repository: ${{ inputs.repository }}"
"text" = "Fork Repository: ${{ inputs.repository }}"
"wrap" = $true
}
@{
Expand All @@ -369,7 +370,7 @@ jobs:
}
@{
"type" = "TextBlock"
"text" = "PR: [View Pull Request](https://github.com/${{ inputs.repository }}/pull/${{ inputs.pr_number }})"
"text" = "PR: [View Pull Request](https://github.com/sparrowapp-dev/sparrow-app/pull/${{ inputs.pr_number }})"
"wrap" = $true
}
@{
Expand All @@ -384,6 +385,11 @@ jobs:
"title" = "📥 Download Windows Installer (.msi)"
"url" = $msiUrl
}
@{
"type" = "Action.OpenUrl"
"title" = "🌐 Open Webapp Preview"
"url" = $webappPreviewUrl
}
)
"$schema" = "http://adaptivecards.io/schemas/adaptive-card.json"
"version" = "1.2"
Expand Down Expand Up @@ -497,6 +503,7 @@ jobs:
ARM64_FILENAME="$(basename "${ARM64_DMG%.dmg}").dmg"

ARM64_URL="https://sparrow-release-assests-dev.s3.us-west-1.amazonaws.com/macos/$ARM64_FILENAME"
WEBAPP_PREVIEW_URL="https://pr-${{ inputs.pr_number }}.preview.sparrowapp.dev"

curl -H "Content-Type: application/json" -d "{
\"type\": \"message\",
Expand All @@ -514,7 +521,7 @@ jobs:
},
{
\"type\": \"TextBlock\",
\"text\": \"Repository: ${{ inputs.repository }}\",
\"text\": \"Fork Repository: ${{ inputs.repository }}\",
\"wrap\": true
},
{
Expand All @@ -524,7 +531,7 @@ jobs:
},
{
\"type\": \"TextBlock\",
\"text\": \"PR: [View Pull Request](https://github.com/${{ inputs.repository }}/pull/${{ inputs.pr_number }})\",
\"text\": \"PR: [View Pull Request](https://github.com/sparrowapp-dev/sparrow-app/pull/${{ inputs.pr_number }})\",
\"wrap\": true
},
{
Expand All @@ -538,6 +545,11 @@ jobs:
\"type\": \"Action.OpenUrl\",
\"title\": \"📥 Download Apple Silicon (arm64)\",
\"url\": \"$ARM64_URL\"
},
{
\"type\": \"Action.OpenUrl\",
\"title\": \"🌐 Open Webapp Preview\",
\"url\": \"$WEBAPP_PREVIEW_URL\"
}
],
\"\$schema\": \"http://adaptivecards.io/schemas/adaptive-card.json\",
Expand Down
183 changes: 183 additions & 0 deletions .github/workflows/sparrow-webapp-pr-preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
name: Webapp PR Preview

on:
workflow_dispatch:
inputs:
branch:
description: 'Branch to build'
required: true
type: string
repository:
description: 'Repository to build from (e.g., owner/repo)'
required: true
type: string
default: 'sparrowapp-dev/sparrow-app'
pr_number:
description: 'Pull Request number'
required: true
type: string

jobs:
build:
runs-on: ubuntu-latest
environment: sparrow_web_Dev
outputs:
preview_url: ${{ steps.deploy_info.outputs.preview_url }}

steps:
- name: Checkout PR branch
uses: actions/checkout@master
with:
repository: ${{ inputs.repository }}
ref: ${{ inputs.branch }}

- name: Azure Container Registry Login
uses: Azure/docker-login@v1
with:
login-server: sparrowprod.azurecr.io
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}

- name: Build and Push Docker Image
run: |
docker build -f ./Sparrow-Web.Dockerfile \
--build-arg PORT=${{ vars.PORT }} \
--build-arg VITE_WEB_API_URL=${{ vars.VITE_WEB_API_URL }} \
--build-arg VITE_WEB_API_TIMEOUT=${{ vars.VITE_WEB_API_TIMEOUT }} \
--build-arg VITE_WEB_ENABLE_MIX_PANEL=${{ vars.VITE_WEB_ENABLE_MIX_PANEL }} \
--build-arg VITE_WEB_MIX_PANEL_TOKEN=${{ vars.VITE_WEB_MIX_PANEL_TOKEN }} \
--build-arg VITE_WEB_SPARROW_SUPPORT_EMAIL=${{ vars.VITE_WEB_SPARROW_SUPPORT_EMAIL }} \
--build-arg VITE_WEB_AUTH_URL=${{ vars.VITE_WEB_AUTH_URL }} \
--build-arg VITE_WEB_SPARROW_GITHUB=${{ vars.VITE_WEB_SPARROW_GITHUB }} \
--build-arg VITE_WEB_SPARROW_DOWNLOAD_LINK=${{ vars.VITE_WEB_SPARROW_DOWNLOAD_LINK }} \
--build-arg VITE_WEB_RELEASE_NOTES_API=${{ vars.VITE_WEB_RELEASE_NOTES_API }} \
--build-arg VITE_WEB_AZURE_CDN_URL=${{ vars.VITE_WEB_AZURE_CDN_URL }} \
--build-arg VITE_WEB_BASE_URL=${{ vars.VITE_WEB_BASE_URL }} \
--build-arg VITE_WEB_SPARROW_LINKEDIN=${{ vars.VITE_WEB_SPARROW_LINKEDIN }} \
--build-arg VITE_WEB_AZURE_INSIGHTS_CONNECTION_STRING=${{ vars.VITE_WEB_AZURE_INSIGHTS_CONNECTION_STRING }} \
--build-arg VITE_WEB_MARKETING_URL=${{ vars.VITE_WEB_MARKETING_URL }} \
--build-arg VITE_WEB_SPARROW_DOCS=${{ vars.VITE_WEB_SPARROW_DOCS }} \
--build-arg VITE_WEB_PROXY_SERVICE=${{ vars.VITE_WEB_PROXY_SERVICE }} \
--build-arg VITE_WEB_SOCKET_IO_API_URL=${{ vars.VITE_WEB_SOCKET_IO_API_URL }} \
--build-arg VITE_WEB_SPARROW_AI_WEBSOCKET=${{ vars.VITE_WEB_SPARROW_AI_WEBSOCKET }} \
--build-arg VITE_WEB_APP_ENVIRONMENT_PATH=${{ vars.VITE_WEB_APP_ENVIRONMENT_PATH }} \
--build-arg VITE_WEB_OPENFEEDBACK_FEEDBACK_URL=${{ vars.VITE_WEB_OPENFEEDBACK_FEEDBACK_URL }} \
--build-arg VITE_WEB_OPENFEEDBACK_BOARD_ID=${{ vars.VITE_WEB_OPENFEEDBACK_BOARD_ID }} \
--build-arg VITE_WEB_SPARROW_WEB_APP_URL=${{ vars.VITE_WEB_SPARROW_WEB_APP_URL }} \
--build-arg VITE_WEB_SENTRY_DSN=${{ vars.VITE_WEB_SENTRY_DSN }} \
--build-arg VITE_WEB_APP_ENVIRONMENT=${{ vars.VITE_WEB_APP_ENVIRONMENT }} \
--build-arg VITE_WEB_POSTHOG_CONNECTION_API_KEY=${{ vars.VITE_WEB_POSTHOG_CONNECTION_API_KEY }} \
--build-arg VITE_WEB_POSTHOG_API_URL=${{ vars.VITE_WEB_POSTHOG_API_URL }} \
--build-arg VITE_WEB_SPARROW_ADMIN_URL=${{ vars.VITE_WEB_SPARROW_ADMIN_URL }} \
--build-arg VITE_WEB_APP_EDITION=${{ vars.VITE_WEB_APP_EDITION }} \
-t sparrowprod.azurecr.io/sparrow-web-preview:pr-${{ inputs.pr_number }} .

docker push sparrowprod.azurecr.io/sparrow-web-preview:pr-${{ inputs.pr_number }}

- name: Set deploy info
id: deploy_info
run: |
echo "preview_url=https://pr-${{ inputs.pr_number }}.preview.sparrowapp.dev" >> $GITHUB_OUTPUT

deploy:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
with:
repository: ${{ inputs.repository }}
ref: ${{ inputs.branch }}

- name: Create preview deployment manifest
run: |
cat > /tmp/preview-deployment.yml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: sparrow-web-pr-${{ inputs.pr_number }}
namespace: sparrow-preview
labels:
app: sparrow-web-preview
pr: "${{ inputs.pr_number }}"
spec:
replicas: 1
selector:
matchLabels:
app: sparrow-web-pr-${{ inputs.pr_number }}
template:
metadata:
labels:
app: sparrow-web-pr-${{ inputs.pr_number }}
spec:
containers:
- name: sparrow-web
image: sparrowprod.azurecr.io/sparrow-web-preview:pr-${{ inputs.pr_number }}
imagePullPolicy: Always
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 300Mi
limits:
cpu: 250m
memory: 400Mi
---
apiVersion: v1
kind: Service
metadata:
name: sparrow-web-pr-${{ inputs.pr_number }}
namespace: sparrow-preview
spec:
selector:
app: sparrow-web-pr-${{ inputs.pr_number }}
ports:
- port: 80
targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: sparrow-web-pr-${{ inputs.pr_number }}
namespace: sparrow-preview
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- pr-${{ inputs.pr_number }}.preview.sparrowapp.dev
secretName: sparrow-web-pr-${{ inputs.pr_number }}-tls
rules:
- host: pr-${{ inputs.pr_number }}.preview.sparrowapp.dev
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: sparrow-web-pr-${{ inputs.pr_number }}
port:
number: 80
EOF

- name: Setup kubectl
uses: azure/setup-kubectl@v2.0

- name: Set Kubernetes context
uses: Azure/k8s-set-context@v2
with:
kubeconfig: ${{ secrets.KUBE_CONFIG }}

- name: Create preview namespace if not exists
run: |
kubectl create namespace sparrow-preview --dry-run=client -o yaml | kubectl apply -f -

- name: Deploy preview
run: |
kubectl apply -f /tmp/preview-deployment.yml

- name: Wait for deployment
run: |
kubectl rollout status deployment/sparrow-web-pr-${{ inputs.pr_number }} \
--namespace=sparrow-preview --timeout=300s
Loading