Skip to content

refactor: Break down monolithic API into modular router structure #22

refactor: Break down monolithic API into modular router structure

refactor: Break down monolithic API into modular router structure #22

Workflow file for this run

name: Beta Release on PR
on:
pull_request:
types: [opened, synchronize, reopened]
workflow_dispatch:
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-deploy:
if: github.actor != 'dependabot[bot]' && (github.event.pull_request.draft == false || github.event_name != 'pull_request')
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
pull-requests: write
issues: write
deployments: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
repository: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }}
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.ref }}
fetch-depth: 0
- name: Prepare deployment variables
id: prepare_deployment
run: |
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
SANITIZED_BRANCH=$(echo "${{ github.head_ref }}" | tr -cs '[:alnum:]' '-' | tr '[:upper:]' '[:lower:]' | sed 's/-$//')
PR_NUMBER="${{ github.event.number }}"
TAG_SUFFIX="pr-${PR_NUMBER}-${TIMESTAMP}"
else
SANITIZED_BRANCH=$(echo "${{ github.ref_name }}" | tr -cs '[:alnum:]' '-' | tr '[:upper:]' '[:lower:]' | sed 's/-$//')
TAG_SUFFIX="manual-${SANITIZED_BRANCH}-${TIMESTAMP}"
fi
echo "sanitized_branch=$SANITIZED_BRANCH" >> $GITHUB_OUTPUT
echo "tag_suffix=$TAG_SUFFIX" >> $GITHUB_OUTPUT
echo "pr_number=${{ github.event.number }}" >> $GITHUB_OUTPUT
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=${{ steps.prepare_deployment.outputs.tag_suffix }}
type=raw,value=beta-{{date 'YYYYMMDD-HHmmss'}}
type=sha,prefix=sha-
labels: |
org.opencontainers.image.title=BioAnalyzer Beta
org.opencontainers.image.description=BioAnalyzer Beta Release for PR Testing
org.opencontainers.image.version=1.0.0-beta
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.revision=${{ github.sha }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Generate deployment URL
id: url
run: |
PR_NUMBER=${{ github.event.number }}
BETA_URL="https://bioanalyzer-beta-$PR_NUMBER.vercel.app"
echo "beta_url=$BETA_URL" >> $GITHUB_OUTPUT
- name: Create deployment comment
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const prNumber = ${{ github.event.number }};
const betaUrl = '${{ steps.url.outputs.beta_url }}';
const comment = "🚀 **Beta Release Ready for Testing**\n\n" +
"🔗 [Live Demo](" + betaUrl + ")";
const comments = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
});
const existingComment = comments.data.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('🚀 **Beta Release Ready for Testing**')
);
if (existingComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existingComment.id,
body: comment
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: comment
});
}
- name: Create deployment
id: deployment
uses: actions/github-script@v7
with:
script: |
const deployment = await github.rest.repos.createDeployment({
owner: context.repo.owner,
repo: context.repo.repo,
ref: context.sha,
environment: 'beta',
description: 'Beta release deployment',
auto_merge: false,
required_contexts: [] // allow deployment without checks
});
core.setOutput("id", deployment.data.id);
- name: Create deployment status
uses: actions/github-script@v7
with:
script: |
const deploymentId = ${{ steps.deployment.outputs.id }};
await github.rest.repos.createDeploymentStatus({
owner: context.repo.owner,
repo: context.repo.repo,
deployment_id: deploymentId,
state: 'success',
environment: 'beta',
description: 'Beta release deployed successfully',
environment_url: '${{ steps.url.outputs.beta_url }}'
});
cleanup:
runs-on: ubuntu-latest
if: github.event.action == 'closed' && github.actor != 'dependabot[bot]'
permissions:
packages: write
pull-requests: write
deployments: write
steps:
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Clean up beta images
run: |
PR_NUMBER=${{ github.event.number }}
echo "Cleaning up beta images for PR #$PR_NUMBER"
docker images --format "table {{.Repository}}:{{.Tag}}" | grep "pr-${PR_NUMBER}" || echo "No PR-specific images found"
echo "Cleanup completed for PR #$PR_NUMBER"
- name: Update PR comment
uses: actions/github-script@v7
with:
script: |
const prNumber = ${{ github.event.number }};
const comment = "🧹 **Beta Release Cleaned Up**\n\n" +
"PR #" + prNumber + " beta release has been cleaned up.";
const comments = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
});
const existingComment = comments.data.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('Beta Release Cleaned Up')
);
if (existingComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existingComment.id,
body: comment
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: comment
});
}