chore(deps): bump modernc.org/sqlite from 1.46.1 to 1.49.1 (#943) #3338
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: CI | |
| on: | |
| pull_request: | |
| branches: [develop, main] | |
| push: | |
| branches: [develop] | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| jobs: | |
| # Detect which files changed to skip expensive jobs on docs-only PRs. | |
| # Push-to-develop always runs the full suite (no path filtering). | |
| changes: | |
| name: Detect Changes | |
| runs-on: ubuntu-latest | |
| outputs: | |
| code: ${{ steps.filter.outputs.code }} | |
| docker: ${{ steps.filter.outputs.docker }} | |
| perf: ${{ steps.filter.outputs.perf }} | |
| scripts: ${{ steps.filter.outputs.scripts }} | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@6c3c2f2c1c457b00c10c4848d6f5491db3b629df # v2.18.0 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| persist-credentials: false | |
| - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v3 | |
| id: filter | |
| with: | |
| filters: | | |
| code: | |
| - '**.go' | |
| - 'go.mod' | |
| - 'go.sum' | |
| - '.golangci.yml' | |
| - '.github/workflows/**' | |
| - 'scripts/hooks/**' | |
| docker: | |
| - 'Dockerfile*' | |
| - 'docker-compose*' | |
| perf: | |
| - 'internal/core/**' | |
| - 'internal/adapters/textfile/**' | |
| - 'go.mod' | |
| scripts: | |
| - 'scripts/**' | |
| - 'justfile' | |
| # Lightweight pass for non-code PRs so required checks aren't stuck pending. | |
| skip-pass: | |
| name: CI Skipped (no code changes) | |
| needs: changes | |
| if: github.event_name == 'pull_request' && needs.changes.outputs.code != 'true' && needs.changes.outputs.docker != 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@6c3c2f2c1c457b00c10c4848d6f5491db3b629df # v2.18.0 | |
| with: | |
| egress-policy: audit | |
| - run: echo "No code changes — Go CI skipped." | |
| # ShellCheck lints shell scripts for common bugs (unquoted vars, missing error | |
| # handling, bashisms in sh scripts, etc.). Currently informational — does NOT | |
| # block merge. To promote to required: | |
| # 1. Fix existing ShellCheck warnings in scripts/*.sh | |
| # 2. Remove `continue-on-error: true` below | |
| # 3. Add "ShellCheck" to the branch ruleset's required status checks | |
| shellcheck: | |
| name: ShellCheck | |
| needs: changes | |
| if: needs.changes.outputs.scripts == 'true' || github.event_name == 'push' | |
| runs-on: ubuntu-latest | |
| continue-on-error: true | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@6c3c2f2c1c457b00c10c4848d6f5491db3b629df # v2.18.0 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install ShellCheck | |
| run: sudo apt-get update && sudo apt-get install -y shellcheck | |
| - name: Lint top-level scripts | |
| run: shellcheck scripts/*.sh | |
| - name: Lint hook scripts | |
| run: shellcheck scripts/hooks/*.sh | |
| quality-gate: | |
| name: Quality Gate | |
| needs: changes | |
| if: needs.changes.outputs.code == 'true' || needs.changes.outputs.docker == 'true' || github.event_name == 'push' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@6c3c2f2c1c457b00c10c4848d6f5491db3b629df # v2.18.0 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| persist-credentials: false | |
| - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 | |
| with: | |
| go-version-file: 'go.mod' | |
| cache-dependency-path: go.sum | |
| - name: Install gofumpt | |
| run: go install mvdan.cc/gofumpt@v0.7.0 | |
| - name: Check formatting (gofumpt) | |
| run: | | |
| UNFORMATTED=$(gofumpt -l .) | |
| if [ -n "$UNFORMATTED" ]; then | |
| echo "::error::Files need formatting with gofumpt:" | |
| echo "$UNFORMATTED" | |
| exit 1 | |
| fi | |
| - name: Run go vet | |
| run: go vet ./... | |
| - name: Run govulncheck | |
| run: | | |
| go install golang.org/x/vuln/cmd/govulncheck@latest | |
| govulncheck ./... | |
| - name: Run golangci-lint | |
| uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9 | |
| with: | |
| version: v2.10.1 | |
| - name: Run tests with coverage and race detector | |
| run: go test ./... -v -count=1 -race -coverprofile=coverage.out -covermode=atomic | |
| - name: Display coverage summary | |
| run: go tool cover -func=coverage.out | |
| - name: Enforce coverage floor | |
| env: | |
| COVERAGE_THRESHOLD: '75' | |
| run: | | |
| COVERAGE=$(go tool cover -func=coverage.out | grep '^total:' | awk '{print $NF}' | tr -d '%') | |
| echo "Total coverage: ${COVERAGE}% (threshold: ${COVERAGE_THRESHOLD}%)" | |
| if [ "$(echo "$COVERAGE < $COVERAGE_THRESHOLD" | bc -l)" -eq 1 ]; then | |
| echo "::error::Coverage ${COVERAGE}% is below the ${COVERAGE_THRESHOLD}% threshold" | |
| exit 1 | |
| fi | |
| - name: Post coverage comment on PR | |
| if: github.event_name == 'pull_request' | |
| continue-on-error: true | |
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const { execSync } = require('child_process'); | |
| const summary = execSync('go tool cover -func=coverage.out').toString(); | |
| const totalLine = summary.split('\n').find(l => l.startsWith('total:')); | |
| const coverage = totalLine ? totalLine.match(/[\d.]+%/)?.[0] : 'unknown'; | |
| const body = `## Coverage Report\n\n**Total coverage: ${coverage}**\n\n<details>\n<summary>Package breakdown</summary>\n\n\`\`\`\n${summary}\`\`\`\n</details>`; | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| }); | |
| const existing = comments.find(c => c.body.startsWith('## Coverage Report')); | |
| if (existing) { | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: existing.id, | |
| body, | |
| }); | |
| } else { | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body, | |
| }); | |
| } | |
| - name: Validate build | |
| run: go build -o /dev/null ./cmd/threedoors | |
| benchmarks: | |
| name: Performance Benchmarks | |
| needs: changes | |
| if: github.event_name == 'push' || (needs.changes.outputs.code == 'true' && needs.changes.outputs.perf == 'true') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@6c3c2f2c1c457b00c10c4848d6f5491db3b629df # v2.18.0 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| persist-credentials: false | |
| - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 | |
| with: | |
| go-version-file: 'go.mod' | |
| cache-dependency-path: go.sum | |
| - name: Run benchmarks | |
| run: go test -bench=. -benchmem -count=3 -run='^$' ./internal/core/ ./internal/adapters/textfile/ | tee benchmark-results.txt | |
| - name: Validate NFR13 (<100ms threshold) | |
| run: go test -run='NFR13' -v -count=1 ./internal/core/ ./internal/adapters/textfile/ | |
| - name: Upload benchmark results | |
| if: always() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: benchmark-results | |
| path: benchmark-results.txt | |
| retention-days: 90 | |
| test-docker-e2e: | |
| name: Docker E2E Tests | |
| if: github.event_name == 'push' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@6c3c2f2c1c457b00c10c4848d6f5491db3b629df # v2.18.0 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4 | |
| - name: Cache Docker layers | |
| uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 | |
| with: | |
| path: /tmp/.buildx-cache | |
| key: ${{ runner.os }}-buildx-${{ hashFiles('Dockerfile.test', 'go.mod', 'go.sum') }} | |
| restore-keys: | | |
| ${{ runner.os }}-buildx- | |
| - name: Build Docker test image | |
| uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7 | |
| with: | |
| context: . | |
| file: Dockerfile.test | |
| load: true | |
| tags: threedoors-test:latest | |
| cache-from: type=local,src=/tmp/.buildx-cache | |
| cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max | |
| - name: Create test-results directory | |
| run: mkdir -p test-results | |
| - name: Run Docker E2E tests | |
| run: docker compose -f docker-compose.test.yml run --rm -T test | |
| - name: Check for golden file diffs | |
| if: always() | |
| run: | | |
| if git diff --name-only | grep -q '\.golden$'; then | |
| echo "::warning::Golden file changes detected:" | |
| git diff -- '*.golden' | |
| else | |
| echo "No golden file changes detected." | |
| fi | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: docker-e2e-results | |
| path: test-results/ | |
| retention-days: 14 | |
| # Rotate buildx cache to prevent unbounded growth | |
| - name: Rotate cache | |
| if: always() | |
| run: | | |
| rm -rf /tmp/.buildx-cache | |
| mv /tmp/.buildx-cache-new /tmp/.buildx-cache 2>/dev/null || true | |
| build-binaries: | |
| name: Build Binaries | |
| needs: quality-gate | |
| if: github.event_name == 'push' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@6c3c2f2c1c457b00c10c4848d6f5491db3b629df # v2.18.0 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| persist-credentials: false | |
| - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 | |
| with: | |
| go-version-file: 'go.mod' | |
| cache-dependency-path: go.sum | |
| - name: Generate version | |
| id: version | |
| run: | | |
| VERSION="0.1.0-alpha.$(date -u +%Y%m%d).$(date -u +%H%M%S).${GITHUB_SHA::7}" | |
| TAG="alpha-$(date -u +%Y%m%d)-$(date -u +%H%M%S)-${GITHUB_SHA::7}" | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| echo "tag=$TAG" >> "$GITHUB_OUTPUT" | |
| - name: Build alpha binaries | |
| run: | | |
| LDFLAGS="-X main.version=${{ steps.version.outputs.version }} -X main.channel=alpha" | |
| GOOS=darwin GOARCH=arm64 go build -ldflags "$LDFLAGS" -o threedoors-a-darwin-arm64 ./cmd/threedoors | |
| GOOS=darwin GOARCH=amd64 go build -ldflags "$LDFLAGS" -o threedoors-a-darwin-amd64 ./cmd/threedoors | |
| GOOS=linux GOARCH=amd64 go build -ldflags "$LDFLAGS" -o threedoors-a-linux-amd64 ./cmd/threedoors | |
| - name: Upload binaries | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: binaries | |
| path: threedoors-* | |
| retention-days: 14 | |
| outputs: | |
| version: ${{ steps.version.outputs.version }} | |
| tag: ${{ steps.version.outputs.tag }} | |
| sign-and-notarize: | |
| name: Sign & Notarize | |
| needs: build-binaries | |
| if: github.event_name == 'push' && vars.SIGNING_ENABLED == 'true' | |
| environment: release | |
| runs-on: macos-latest | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@6c3c2f2c1c457b00c10c4848d6f5491db3b629df # v2.18.0 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Download binaries | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: binaries | |
| - name: Import certificates | |
| env: | |
| APPLE_CERTIFICATE_P12: ${{ secrets.APPLE_CERTIFICATE_P12 }} | |
| APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} | |
| run: | | |
| # Create temporary keychain | |
| security create-keychain -p "" build.keychain | |
| security default-keychain -s build.keychain | |
| security unlock-keychain -p "" build.keychain | |
| # Import application certificate | |
| echo "$APPLE_CERTIFICATE_P12" | base64 --decode > cert.p12 | |
| security import cert.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign | |
| rm cert.p12 | |
| # Install Apple Developer ID G2 intermediate certificate | |
| curl -sfo /tmp/DeveloperIDG2CA.cer https://www.apple.com/certificateauthority/DeveloperIDG2CA.cer | |
| security add-certificates -k build.keychain /tmp/DeveloperIDG2CA.cer | |
| rm /tmp/DeveloperIDG2CA.cer | |
| # Allow codesign to access keychain without prompting | |
| security set-key-partition-list -S apple-tool:,apple: -s -k "" build.keychain | |
| - name: Verify certificate import | |
| run: | | |
| echo "Listing signing identities:" | |
| security find-identity -v build.keychain | |
| - name: Sign darwin binaries | |
| env: | |
| APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }} | |
| run: | | |
| codesign --force --options runtime --sign "$APPLE_SIGNING_IDENTITY" --identifier "com.arcavenae.threedoors-a" --timestamp threedoors-a-darwin-arm64 | |
| codesign --force --options runtime --sign "$APPLE_SIGNING_IDENTITY" --identifier "com.arcavenae.threedoors-a" --timestamp threedoors-a-darwin-amd64 | |
| - name: Verify signatures | |
| run: | | |
| codesign --verify --deep --strict threedoors-a-darwin-arm64 | |
| codesign --verify --deep --strict threedoors-a-darwin-amd64 | |
| - name: Upload signed alpha binaries | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: signed-binaries | |
| path: | | |
| threedoors-a-darwin-arm64 | |
| threedoors-a-darwin-amd64 | |
| retention-days: 14 | |
| - name: Cleanup keychain | |
| if: always() | |
| run: security delete-keychain build.keychain || true | |
| release: | |
| name: Create Release | |
| needs: [build-binaries, sign-and-notarize] | |
| if: github.event_name == 'push' && !cancelled() && needs.build-binaries.result == 'success' | |
| permissions: | |
| contents: write | |
| environment: release | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@6c3c2f2c1c457b00c10c4848d6f5491db3b629df # v2.18.0 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| persist-credentials: false | |
| # Try signed binaries first, fall back to unsigned | |
| - name: Download signed binaries | |
| if: needs.sign-and-notarize.result == 'success' | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: signed-binaries | |
| - name: Download unsigned binaries (fallback) | |
| if: needs.sign-and-notarize.result != 'success' | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: binaries | |
| - name: Download all binaries (for linux) | |
| if: needs.sign-and-notarize.result == 'success' | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: binaries | |
| path: unsigned-binaries | |
| - name: Copy linux binary from unsigned artifacts | |
| if: needs.sign-and-notarize.result == 'success' | |
| run: | | |
| cp unsigned-binaries/threedoors-a-linux-amd64 . | |
| rm -rf unsigned-binaries | |
| - name: List release files | |
| run: ls -la threedoors-* 2>/dev/null || true | |
| - name: Create GitHub Release | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| TAG: ${{ needs.build-binaries.outputs.tag }} | |
| VERSION: ${{ needs.build-binaries.outputs.version }} | |
| COMMIT: ${{ github.sha }} | |
| SIGNED: ${{ needs.sign-and-notarize.result == 'success' && 'Yes (Apple Developer ID)' || 'No (unsigned)' }} | |
| run: | | |
| BODY="Automated alpha release from merge to develop. | |
| **Version:** ${VERSION} | |
| **Commit:** ${COMMIT} | |
| **Signed:** ${SIGNED} | |
| **Alpha Binaries:** | |
| - \`threedoors-a-darwin-arm64\` — Alpha macOS Apple Silicon | |
| - \`threedoors-a-darwin-amd64\` — Alpha macOS Intel | |
| - \`threedoors-a-linux-amd64\` — Alpha Linux x86_64 | |
| **Homebrew (alpha):** \`brew install arcavenae/tap/threedoors-a\`" | |
| ASSETS=() | |
| for f in threedoors-*; do | |
| [ -f "$f" ] && ASSETS+=("$f") | |
| done | |
| gh release create "$TAG" \ | |
| --title "Alpha ${TAG}" \ | |
| --notes "$BODY" \ | |
| --prerelease \ | |
| "${ASSETS[@]}" | |
| # Gated by repository variable — set vars.ALPHA_TAP_ENABLED to 'true' | |
| # in GitHub Settings > Actions > Variables to activate alpha formula publishing. | |
| # The alpha GitHub release is always created; only the tap push is controlled. | |
| - name: Update alpha Homebrew formula | |
| if: vars.ALPHA_TAP_ENABLED == 'true' | |
| env: | |
| HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }} | |
| run: | | |
| VERSION="${{ needs.build-binaries.outputs.version }}" | |
| TAG="${{ needs.build-binaries.outputs.tag }}" | |
| BASE_URL="https://github.com/arcavenae/ThreeDoors/releases/download/${TAG}" | |
| # Compute SHA256 checksums for alpha binaries | |
| SHA_ARM64=$(sha256sum threedoors-a-darwin-arm64 | cut -d' ' -f1) | |
| SHA_AMD64=$(sha256sum threedoors-a-darwin-amd64 | cut -d' ' -f1) | |
| SHA_LINUX=$(sha256sum threedoors-a-linux-amd64 | cut -d' ' -f1) | |
| # Generate formula | |
| cat > threedoors-a.rb <<FORMULA | |
| class ThreedoorsA < Formula | |
| desc "TUI task manager — alpha channel (updated on every develop push)" | |
| homepage "https://github.com/arcavenae/ThreeDoors" | |
| version "${VERSION}" | |
| license "MIT" | |
| if OS.mac? && Hardware::CPU.arm? | |
| url "${BASE_URL}/threedoors-a-darwin-arm64" | |
| sha256 "${SHA_ARM64}" | |
| elsif OS.mac? | |
| url "${BASE_URL}/threedoors-a-darwin-amd64" | |
| sha256 "${SHA_AMD64}" | |
| elsif OS.linux? | |
| url "${BASE_URL}/threedoors-a-linux-amd64" | |
| sha256 "${SHA_LINUX}" | |
| end | |
| def install | |
| if OS.mac? && Hardware::CPU.arm? | |
| bin.install "threedoors-a-darwin-arm64" => "threedoors-a" | |
| elsif OS.mac? | |
| bin.install "threedoors-a-darwin-amd64" => "threedoors-a" | |
| elsif OS.linux? | |
| bin.install "threedoors-a-linux-amd64" => "threedoors-a" | |
| end | |
| end | |
| test do | |
| assert_match "ThreeDoors", shell_output("#{bin}/threedoors-a --version 2>&1") | |
| end | |
| end | |
| FORMULA | |
| # Remove leading whitespace from heredoc indentation | |
| sed -i 's/^ //' threedoors-a.rb | |
| # Validate Ruby syntax before pushing | |
| ruby -c threedoors-a.rb | |
| # Clone tap repo, update formula, push | |
| git clone "https://x-access-token:${HOMEBREW_TAP_TOKEN}@github.com/arcavenae/homebrew-tap.git" tap-repo | |
| mkdir -p tap-repo/Formula | |
| cp threedoors-a.rb tap-repo/Formula/threedoors-a.rb | |
| cd tap-repo | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git add Formula/threedoors-a.rb | |
| if git diff --cached --quiet; then | |
| echo "Formula unchanged, skipping push" | |
| else | |
| git commit -m "chore(formula): update threedoors-a to ${TAG}" | |
| git push origin main | |
| fi | |
| - name: Clean up old alpha releases | |
| continue-on-error: true | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| gh release list --limit 200 \ | |
| | grep 'alpha-' \ | |
| | tail -n +31 \ | |
| | awk '{print $1}' \ | |
| | xargs -I{} gh release delete {} --yes --cleanup-tag | |