Skip to content
Merged
Changes from 1 commit
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
209 changes: 209 additions & 0 deletions .github/workflows/build-push-greenhouse-pr-preview.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
# Workflow Flow:
# Initial Setup:
# 1. Developer sets 'greenhouse-pr-build' label on PR
# 2. Action builds Docker image with tag pr-{number}-{sha}
# 3. Action sets 'greenhouse-pr-preview' label (ArgoCD deploys)
#
# On subsequent commits:
# 1. Developer pushes new commit
# 2. PR-Build label already exists
# 3. Action removes PR-Preview label (ArgoCD deletes the app)
# 4. Action builds new Docker image with new tag pr-{number}-{new-sha}
# 5. Action sets PR-Preview label back (ArgoCD redeploys after 2-3 mins)
#
# On PR close/merge:
# 1. PR is closed or merged
# 2. Action deletes all Docker images matching pr-{number}-*
# 3. Action removes PR-Preview label

name: Build Greenhouse PR Preview 🔬

on:
pull_request:
types: [ labeled, synchronize, opened, reopened, closed ]
paths:
- "apps/greenhouse/**"
Comment thread
ArtieReus marked this conversation as resolved.
Outdated

Comment thread
ArtieReus marked this conversation as resolved.
env:
REGISTRY: ghcr.io
IMAGE_NAME: "juno-app-greenhouse-pr-preview"
PACKAGE_PATH: "apps/greenhouse"
PR_BUILD_LABEL: "greenhouse-pr-build"
PR_PREVIEW_LABEL: "greenhouse-pr-preview"

Comment thread
ArtieReus marked this conversation as resolved.
jobs:
build-and-push:
name: Build and Push PR Preview Image
runs-on: ubuntu-latest
Comment thread
ArtieReus marked this conversation as resolved.
permissions:
contents: read
packages: write
pull-requests: write
Comment thread
ArtieReus marked this conversation as resolved.
Outdated
steps:
- name: Check for PR Build label
id: check-label
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const labels = context.payload.pull_request.labels.map(l => l.name);
const hasPrBuildLabel = labels.includes('${{ env.PR_BUILD_LABEL }}');
const hasPrPreviewLabel = labels.includes('${{ env.PR_PREVIEW_LABEL }}');

console.log(`PR Build Label present: ${hasPrBuildLabel}`);
console.log(`PR Preview Label present: ${hasPrPreviewLabel}`);
console.log(`Event action: ${context.payload.action}`);

core.setOutput('should-build', hasPrBuildLabel.toString());
core.setOutput('has-preview-label', hasPrPreviewLabel.toString());

- name: Exit if PR Build label not present
if: steps.check-label.outputs.should-build != 'true'
run: |
echo "Skipping build - '${{ env.PR_BUILD_LABEL }}' label not present"
exit 0

- name: Remove PR Preview label on new commit
if: steps.check-label.outputs.should-build == 'true' &&
steps.check-label.outputs.has-preview-label == 'true' &&
github.event.action == 'synchronize'
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
console.log('Removing PR Preview label - new commit detected');
try {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
name: '${{ env.PR_PREVIEW_LABEL }}'
});
console.log('PR Preview label removed successfully');
} catch (error) {
if (error.status === 404) {
console.log('Label already removed or does not exist');
} else {
throw error;
}
}

- name: Checkout repository
if: steps.check-label.outputs.should-build == 'true'
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.event.pull_request.head.sha }}

- name: Generate PR version tag
if: steps.check-label.outputs.should-build == 'true'
id: pr-version
run: |
PR_NUMBER=${{ github.event.pull_request.number }}
SHORT_SHA=$(echo ${{ github.event.pull_request.head.sha }} | cut -c1-7)
PR_VERSION="pr-${PR_NUMBER}-${SHORT_SHA}"
echo "PR_VERSION=${PR_VERSION}" >> $GITHUB_OUTPUT
echo "Building version: ${PR_VERSION}"

- name: Log into registry ${{ env.REGISTRY }}
if: steps.check-label.outputs.should-build == 'true'
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Generate Docker metadata
if: steps.check-label.outputs.should-build == 'true'
id: meta
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
with:
images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=${{ steps.pr-version.outputs.PR_VERSION }}
labels: |
org.opencontainers.image.description=PR Preview for Greenhouse Dashboard
org.opencontainers.image.title=Greenhouse-UI-PR-${{ github.event.pull_request.number }}

- name: Build and push Docker image
if: steps.check-label.outputs.should-build == 'true'
id: build-image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
file: ${{ env.PACKAGE_PATH }}/docker/Dockerfile

- name: Add PR Preview label
if: steps.check-label.outputs.should-build == 'true' && success()
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
labels: ['${{ env.PR_PREVIEW_LABEL }}']
});

cleanup:
name: Cleanup PR Preview Image
if: github.event.action == 'closed'
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
pull-requests: write
steps:
- name: Log into registry ${{ env.REGISTRY }}
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Install crane
run: |
VERSION="latest"
OS="Linux"
ARCH="x86_64"

curl -sL "https://github.com/google/go-containerregistry/releases/${VERSION}/download/go-containerregistry_${OS}_${ARCH}.tar.gz" | tar -xz crane
chmod +x crane
sudo mv crane /usr/local/bin/crane
Comment thread
ArtieReus marked this conversation as resolved.
Outdated

crane version

Comment thread
ArtieReus marked this conversation as resolved.
- name: Delete PR preview images
run: |
PR_NUMBER=${{ github.event.pull_request.number }}
IMAGE_BASE="${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}"

echo "Looking for images matching pr-${PR_NUMBER}-*"

# List all tags and delete matching ones
crane ls "${IMAGE_BASE}" | grep "^pr-${PR_NUMBER}-" | while read tag; do
echo "Deleting ${IMAGE_BASE}:${tag}"
crane delete "${IMAGE_BASE}:${tag}" || echo "Failed to delete ${IMAGE_BASE}:${tag}"
done

Comment thread
ArtieReus marked this conversation as resolved.
Outdated
echo "Cleanup completed for PR ${PR_NUMBER}"

- name: Remove PR Preview label
Comment thread
ArtieReus marked this conversation as resolved.
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
try {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
name: '${{ env.PR_PREVIEW_LABEL }}'
});
console.log('PR Preview label removed successfully');
} catch (error) {
if (error.status === 404) {
console.log('Label does not exist or already removed');
} else {
console.error('Error removing label:', error);
Comment thread
ArtieReus marked this conversation as resolved.
}
}
Loading