Modify LiteFS config for PR preview to use static lease type #3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: π PR Preview Deploy | ||
| on: | ||
| pull_request: | ||
| types: [opened, synchronize, reopened, closed] | ||
| env: | ||
| FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} | ||
| jobs: | ||
| deploy-pr: | ||
| name: π Deploy PR Preview | ||
| runs-on: ubuntu-latest | ||
| if: github.event.action != 'closed' | ||
| steps: | ||
| - name: β¬οΈ Checkout repo | ||
| uses: actions/checkout@v4 | ||
| - name: π Setup Fly | ||
| uses: superfly/flyctl-actions/[email protected] | ||
| - name: π·οΈ Generate app name | ||
| id: app-name | ||
| run: | | ||
| # Create a unique app name for this PR | ||
| APP_NAME="kcd-pr-${{ github.event.number }}" | ||
| echo "app_name=$APP_NAME" >> $GITHUB_OUTPUT | ||
| echo "url=https://$APP_NAME.fly.dev" >> $GITHUB_OUTPUT | ||
| - name: π Setup PR-specific configurations | ||
| run: | | ||
| # Copy and modify fly.toml for PR preview | ||
| cp fly.toml fly.toml.backup | ||
| # Update app name for PR | ||
| sed -i 's/^app = .*/app = "${{ steps.app-name.outputs.app_name }}"/' fly.toml | ||
| # Remove consul from experimental section (if present) | ||
| sed -i '/enable_consul = true/d' fly.toml | ||
| # Add auto-scaling configuration to services section | ||
| # Find the [[services]] section and add auto-scaling after internal_port | ||
| awk ' | ||
| /^\[\[services\]\]/ { in_services = 1 } | ||
| /^ internal_port = / && in_services { | ||
| print $0 | ||
| print " auto_stop_machines = true" | ||
| print " auto_start_machines = true" | ||
| print " min_machines_running = 0" | ||
| print " processes = [\"app\"]" | ||
| in_services = 0 | ||
| next | ||
| } | ||
| { print } | ||
| ' fly.toml > fly.toml.tmp && mv fly.toml.tmp fly.toml | ||
| # Copy and modify litefs.yml for PR preview (standalone, no consul) | ||
| cp other/litefs.yml other/litefs.yml.backup | ||
| # Replace consul lease with static lease for PR preview isolation | ||
| # This makes each PR preview a standalone instance | ||
| sed -i '/^lease:/,/^$/c\ | ||
| lease:\ | ||
| type: '\''static'\'' | ||
| ' other/litefs.yml | ||
| # Add a comment explaining the isolation | ||
| sed -i '/^lease:/i\\n# PR Preview: Using static lease type for standalone instance\n# This prevents syncing with production data' other/litefs.yml | ||
| echo "=== Modified fly.toml ===" | ||
| cat fly.toml | ||
| echo "=== Modified litefs.yml ===" | ||
| cat other/litefs.yml | ||
| - name: ποΈ Create PR app | ||
| run: | | ||
| flyctl apps create ${{ steps.app-name.outputs.app_name }} --org personal || echo "App already exists" | ||
| - name: π Deploy PR app | ||
| run: | | ||
| flyctl deploy --depot --remote-only --build-arg COMMIT_SHA=${{ github.sha }} --app ${{ steps.app-name.outputs.app_name }} | ||
| - name: π¬ Comment on PR | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| script: | | ||
| const { data: comments } = await github.rest.issues.listComments({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: context.issue.number, | ||
| }); | ||
| const botComment = comments.find(comment => | ||
| comment.user.type === 'Bot' && comment.body.includes('PR Preview') | ||
| ); | ||
| const commentBody = `π **PR Preview Deployed** | ||
| Your pull request has been deployed to a temporary Fly machine: | ||
| π **Preview URL**: ${{ steps.app-name.outputs.url }} | ||
| π± **App Name**: \`${{ steps.app-name.outputs.app_name }}\` | ||
| This preview will automatically scale to zero when not in use to save costs. | ||
| The app will be automatically deleted when this PR is closed or merged. | ||
| --- | ||
| <sub>Updated: ${new Date().toISOString()}</sub>`; | ||
| if (botComment) { | ||
| github.rest.issues.updateComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| comment_id: botComment.id, | ||
| body: commentBody | ||
| }); | ||
| } else { | ||
| github.rest.issues.createComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: context.issue.number, | ||
| body: commentBody | ||
| }); | ||
| } | ||
| cleanup-pr: | ||
| name: π§Ή Cleanup PR Preview | ||
| runs-on: ubuntu-latest | ||
| if: github.event.action == 'closed' | ||
| steps: | ||
| - name: π Setup Fly | ||
| uses: superfly/flyctl-actions/[email protected] | ||
| - name: π·οΈ Generate app name | ||
| id: app-name | ||
| run: | | ||
| APP_NAME="kcd-pr-${{ github.event.number }}" | ||
| echo "app_name=$APP_NAME" >> $GITHUB_OUTPUT | ||
| - name: ποΈ Delete PR app | ||
| run: | | ||
| flyctl apps destroy ${{ steps.app-name.outputs.app_name }} --yes || echo "App doesn't exist or already deleted" | ||
| - name: π¬ Comment on PR | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| script: | | ||
| const commentBody = `π§Ή **PR Preview Cleaned Up** | ||
| The temporary Fly machine for this PR has been deleted. | ||
| --- | ||
| <sub>Cleaned up: ${new Date().toISOString()}</sub>`; | ||
| github.rest.issues.createComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: context.issue.number, | ||
| body: commentBody | ||
| }); | ||