All skills
patricio0312rev avatar

/preview-environments-builder

@63451c7

Creates ephemeral preview deployments for each pull request with automatic deployment, unique URLs, and cleanup on PR close. Use for "preview deployments", "PR environments", "ephemeral environments", or "review apps".

Use this Skill: https://skilld.dev/gh/patricio0312rev/skills/preview-environments-builder

This session only. Nothing lands on disk.

SKILL.md

≈62 tokens always: the name and description. ≈1.3k when used: this file.

Preview Environments Builder

Deploy isolated preview environments for every pull request.

Vercel Preview Deployment

# .github/workflows/preview.yml
name: Preview Deployment

on:
  pull_request:
    types: [opened, synchronize, reopened]

jobs:
  deploy-preview:
    runs-on: ubuntu-latest
    environment:
      name: preview-${{ github.event.pull_request.number }}
      url: ${{ steps.deploy.outputs.url }}

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "npm"

      - run: npm ci
      - run: npm run build

      - name: Deploy to Vercel
        id: deploy
        uses: amondnet/vercel-action@v25
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
          scope: ${{ secrets.VERCEL_ORG_ID }}
          alias-domains: pr-${{ github.event.pull_request.number }}.myapp.dev

      - name: Comment PR
        uses: actions/github-script@v7
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `✅ Preview deployed!\n\n🔗 **URL:** ${{ steps.deploy.outputs.url }}\n\nCommit: ${context.sha.substring(0, 7)}`
            })

Docker-based Preview

preview:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4

    - name: Build Docker image
      run: |
        docker build -t myapp:pr-${{ github.event.pull_request.number }} .

    - name: Deploy to Kubernetes
      run: |
        kubectl create namespace pr-${{ github.event.pull_request.number }} || true
        kubectl apply -f k8s/preview.yml \
          --namespace pr-${{ github.event.pull_request.number }}
        kubectl set image deployment/myapp \
          myapp=myapp:pr-${{ github.event.pull_request.number }} \
          --namespace pr-${{ github.event.pull_request.number }}

    - name: Get preview URL
      id: url
      run: |
        URL=$(kubectl get ingress myapp \
          --namespace pr-${{ github.event.pull_request.number }} \
          -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
        echo "url=https://pr-${{ github.event.pull_request.number }}.preview.myapp.com" >> $GITHUB_OUTPUT

    - name: Comment PR
      uses: actions/github-script@v7
      with:
        script: |
          github.rest.issues.createComment({
            issue_number: context.issue.number,
            owner: context.repo.owner,
            repo: context.repo.repo,
            body: `🚀 Preview deployed to: ${{ steps.url.outputs.url }}`
          })

Cleanup on PR Close

# .github/workflows/cleanup-preview.yml
name: Cleanup Preview

on:
  pull_request:
    types: [closed]

jobs:
  cleanup:
    runs-on: ubuntu-latest
    steps:
      - name: Delete Vercel deployment
        uses: actions/github-script@v7
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const deployments = await github.rest.repos.listDeployments({
              owner: context.repo.owner,
              repo: context.repo.repo,
              environment: `preview-${context.issue.number}`
            });

            for (const deployment of deployments.data) {
              await github.rest.repos.createDeploymentStatus({
                owner: context.repo.owner,
                repo: context.repo.repo,
                deployment_id: deployment.id,
                state: 'inactive'
              });

              await github.rest.repos.deleteDeployment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                deployment_id: deployment.id
              });
            }

      - name: Cleanup Kubernetes namespace
        run: |
          kubectl delete namespace pr-${{ github.event.pull_request.number }} --ignore-not-found=true

Environment Naming

# Consistent naming pattern
environment:
  name: preview-pr-${{ github.event.pull_request.number }}
  url: https://pr-${{ github.event.pull_request.number }}.preview.myapp.com

Database Seeding

- name: Setup preview database
  run: |
    # Create database
    psql -c "CREATE DATABASE preview_pr_${{ github.event.pull_request.number }};"

    # Seed with test data
    npm run db:seed -- --database=preview_pr_${{ github.event.pull_request.number }}
  env:
    DATABASE_URL: ${{ secrets.PREVIEW_DB_URL }}

Best Practices

  1. Unique URLs: pr-{number}.preview.domain.com
  2. Auto cleanup: Delete on PR close
  3. Comment on PR: Link to preview
  4. Environment protection: Require approval
  5. Resource limits: Prevent abuse
  6. TTL: Auto-delete after 7 days
  7. Secrets management: Use preview-specific secrets

Output Checklist

  • Preview deployment workflow
  • Unique URL generation
  • PR comment with link
  • Cleanup workflow on close
  • Environment naming strategy
  • Database seeding (if needed)
  • Resource limits configured

Source: SKILL.md on GitHub

1 warning17d5 checks · Risk SAFE
  • Gen Agent Trust Hub17d

    The skill provides workflow templates and configuration guidelines for building ephemeral preview environments using GitHub Actions, Vercel, and Kubernetes. It adheres to security best practices for secret management and utilizes standard, well-known CI/CD tools.

  • Socket17d

    1 alert: gptAnomaly

  • Snyk17d

    Risk: LOW · No issues

  • Runlayer7mo

    1/1 file flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 63451c7. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Dormantupdated 9 months ago

README badge

README badge for patricio0312rev/skills/preview-environments-builder