Cleanup Old Deployments #2289
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: Cleanup Old Deployments | |
| on: | |
| # Run daily at midnight UTC | |
| schedule: | |
| - cron: '0 * * * *' | |
| # Allow manual trigger | |
| workflow_dispatch: | |
| inputs: | |
| keep_count: | |
| description: 'Number of recent deployments to keep' | |
| required: false | |
| default: '1' | |
| jobs: | |
| cleanup: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| deployments: write | |
| steps: | |
| - name: Delete old deployments | |
| uses: strumwolf/delete-deployment-environment@v3 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| environment: Preview | |
| onlyRemoveDeployments: true | |
| onlyDeactivateDeployments: false | |
| - name: Cleanup inactive deployments | |
| uses: actions/github-script@v7 | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| script: | | |
| const owner = context.repo.owner; | |
| const repo = context.repo.repo; | |
| const defaultKeepCount = parseInt('${{ github.event.inputs.keep_count }}' || '1'); | |
| // Keep more production deployments for rollback capability | |
| const keepCountByEnv = { | |
| 'Production': 3, | |
| 'Preview': defaultKeepCount, | |
| 'datastoria (Production)': 1 | |
| }; | |
| // Get all deployments | |
| const deployments = await github.paginate( | |
| github.rest.repos.listDeployments, | |
| { owner, repo, per_page: 100 } | |
| ); | |
| console.log(`Found ${deployments.length} total deployments`); | |
| // Group by environment | |
| const byEnv = {}; | |
| for (const d of deployments) { | |
| const env = d.environment || 'unknown'; | |
| if (!byEnv[env]) byEnv[env] = []; | |
| byEnv[env].push(d); | |
| } | |
| // For each environment, keep only the most recent ones | |
| for (const [env, deps] of Object.entries(byEnv)) { | |
| // Sort by created_at descending | |
| deps.sort((a, b) => new Date(b.created_at) - new Date(a.created_at)); | |
| // Use environment-specific keep count, fallback to default | |
| const keepCount = keepCountByEnv[env] || defaultKeepCount; | |
| // Skip the ones we want to keep | |
| const toDelete = deps.slice(keepCount); | |
| console.log(`Environment "${env}": keeping ${Math.min(keepCount, deps.length)}, deleting ${toDelete.length}`); | |
| for (const deployment of toDelete) { | |
| try { | |
| // First, set deployment to inactive | |
| await github.rest.repos.createDeploymentStatus({ | |
| owner, | |
| repo, | |
| deployment_id: deployment.id, | |
| state: 'inactive' | |
| }); | |
| // Then delete the deployment | |
| await github.rest.repos.deleteDeployment({ | |
| owner, | |
| repo, | |
| deployment_id: deployment.id | |
| }); | |
| console.log(`Deleted deployment ${deployment.id} (${deployment.environment})`); | |
| } catch (error) { | |
| console.log(`Failed to delete deployment ${deployment.id}: ${error.message}`); | |
| } | |
| } | |
| } |