Skip to content

chore: add previous build cleanup scripts#1682

Merged
elibosley merged 1 commit into
mainfrom
chore/build-cleanup
Sep 9, 2025
Merged

chore: add previous build cleanup scripts#1682
elibosley merged 1 commit into
mainfrom
chore/build-cleanup

Conversation

@elibosley

@elibosley elibosley commented Sep 9, 2025

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • Chores
    • Added automated cleanup of preview builds older than seven days to reduce storage usage; runs on non-release pushes and won’t fail the build if cleanup issues occur.
    • Introduced a tool to optionally remove all pull request preview builds with confirmation and clear summaries.
    • Updated CI behavior to cancel in-progress runs only for pull requests; pushes and releases are no longer auto-canceled.

@coderabbitai

coderabbitai Bot commented Sep 9, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Adds automated cleanup for preview and PR builds stored in Cloudflare R2, via a new step in build-plugin workflow and two new Bash scripts. Updates main workflow concurrency to cancel only on pull_request events. No changes to exported/public APIs.

Changes

Cohort / File(s) Summary
GitHub Workflows
.github/workflows/build-plugin.yml, .github/workflows/main.yml
build-plugin: adds a conditional, continue-on-error cleanup step for old preview builds using AWS CLI against Cloudflare R2; main: makes cancel-in-progress conditional on event type (pull_request only).
Cleanup Scripts (R2 via AWS CLI)
scripts/cleanup-old-builds.sh, scripts/cleanup-pr-builds.sh
New scripts to list and delete old timestamped preview builds and PR-tagged builds under unraid-api/* in R2; validate CF env vars, compute cutoffs, prompt for confirmation, perform deletions, and summarize results.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Dev as Developer
  participant GH as GitHub Actions (build-plugin)
  participant R2 as Cloudflare R2 (S3 API)
  Note over GH: On push and not a release
  GH->>R2: List s3://CF_BUCKET_PREVIEW/unraid-api/* (endpoint=CF_ENDPOINT)
  GH->>GH: Filter filenames by regex and 7-day cutoff
  alt Old files found
    loop For each old file
      GH->>R2: aws s3 rm s3://.../dynamix.unraid.net-YYYY.MM.DD.HHMM.txz
      Note right of GH: continue-on-error
    end
    GH-->>Dev: Log deletions count
  else None found
    GH-->>Dev: Log "no old files" message
  end
Loading
sequenceDiagram
  autonumber
  actor Op as Operator
  participant Script1 as scripts/cleanup-old-builds.sh
  participant R2 as Cloudflare R2 (S3 API)
  Op->>Script1: Run [keep_days?]
  Script1->>Script1: Validate CF_* env vars
  Script1->>R2: List preview builds under unraid-api/
  Script1->>Script1: Partition OLD vs KEEP by cutoff
  alt Confirm deletion
    loop Each OLD file
      Script1->>R2: aws s3 rm s3://.../file
    end
    Script1-->>Op: Summary (deleted/failed)
  else Cancel
    Script1-->>Op: Aborted
  end
Loading
sequenceDiagram
  autonumber
  actor Op as Operator
  participant Script2 as scripts/cleanup-pr-builds.sh
  participant R2 as Cloudflare R2 (S3 API)
  Op->>Script2: Run
  Script2->>Script2: Validate CF_* env vars
  Script2->>R2: List PR build prefixes under unraid-api/tag/
  alt PR builds found
    Script2-->>Op: Prompt to delete all
    alt Confirm
      loop Each PR prefix
        Script2->>R2: aws s3 rm --recursive s3://.../unraid-api/tag/<PR>
      end
      Script2-->>Op: Cleanup summary and verification
    else Cancel
      Script2-->>Op: Aborted
    end
  else None found
    Script2-->>Op: "No PR builds"
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Pre-merge checks (2 passed, 1 inconclusive)

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Description Check ❓ Inconclusive The pull request description is missing or lacks substantive details about the changes, making it unclear whether it corresponds to the modifications introduced. A fuller description would help reviewers understand the scope and intent beyond the title. Without any descriptive content, this check is inconclusive. Please update the PR description to summarize the key changes, including the added cleanup scripts and workflow modifications, and explain their purpose and usage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The current title succinctly conveys that the PR adds scripts to clean up previous builds, which is the main feature introduced in this changeset. It is clear, concise, and specific enough for a teammate to understand the high-level purpose without delving into details. The title does not cover every modification, such as the small workflow updates, but that level of detail isn’t necessary for a good PR title.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Poem

I hop through buckets, tidy and spry,
Sweeping old builds with a wink of an eye.
PR crumbs vanish—poof!—into air,
Seven-day echoes left light as a hare.
Workflows hum softly, canceling with grace,
My whiskers approve this cleaner place. 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/build-cleanup

Comment @coderabbitai help to get the list of available commands and usage tips.

@claude

claude Bot commented Sep 9, 2025

Copy link
Copy Markdown

Claude finished @elibosley's task —— View job


PR Review: Build Cleanup Scripts

Analyzing the changes for critical issues in the diff/changeset:

Todo List:

  • Read changed files to understand the diff
  • Analyze cleanup scripts for security/data loss risks
  • Check workflow modifications for breaking changes
  • Provide targeted review feedback

Analysis Results:

🔍 CRITICAL SECURITY ISSUE FOUND:

Line 204 in .github/workflows/build-plugin.yml: The new cleanup logic embedded in the workflow uses unquoted regex patterns that are vulnerable to command injection:

grep -E "dynamix\.unraid\.net-[0-9]{4}\.[0-9]{2}\.[0-9]{2}\.[0-9]{4}\.txz"

Risk: If S3 bucket contents are maliciously crafted, the grep -E could be exploited for command execution in the GitHub Actions environment.

Recommendation: Use the standalone cleanup scripts instead of embedded bash in workflows, as they properly validate and sanitize inputs with proper quoting and safer string operations.

--- | Branch: chore/build-cleanup

@codecov

codecov Bot commented Sep 9, 2025

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 58.58%. Comparing base (6ed2f5c) to head (da43c39).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1682   +/-   ##
=======================================
  Coverage   58.58%   58.58%           
=======================================
  Files         624      624           
  Lines       30769    30769           
  Branches     3618     3618           
=======================================
  Hits        18026    18026           
  Misses      12706    12706           
  Partials       37       37           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Sep 9, 2025

Copy link
Copy Markdown
Contributor

This plugin has been deployed to Cloudflare R2 and is available for testing.
Download it at this URL:

https://preview.dl.unraid.net/unraid-api/tag/PR1682/dynamix.unraid.net.plg

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (9)
.github/workflows/build-plugin.yml (3)

187-222: Count only successful deletions; hardcoded prefix; add pipefail

  • Count increments even on failed rm (due to || true). Track successes/failures separately.
  • Use ${{ inputs.BUCKET_PATH }} instead of hardcoded unraid-api/ to future-proof.
  • Add set -euo pipefail to avoid masked errors in pipelines.
       - name: Clean up old preview builds
         if: inputs.RELEASE_CREATED == 'false' && github.event_name == 'push'
         continue-on-error: true
         env:
           AWS_ACCESS_KEY_ID: ${{ secrets.CF_ACCESS_KEY_ID }}
           AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_SECRET_ACCESS_KEY }}
           AWS_DEFAULT_REGION: auto
         run: |
-          echo "🧹 Cleaning up old preview builds (keeping last 7 days)..."
+          set -euo pipefail
+          echo "🧹 Cleaning up old preview builds (keeping last 7 days)..."
           
           # Calculate cutoff date (7 days ago)
           CUTOFF_DATE=$(date -d "7 days ago" +"%Y.%m.%d")
           echo "Deleting builds older than: ${CUTOFF_DATE}"
           
           # List and delete old timestamped .txz files
-          OLD_FILES=$(aws s3 ls "s3://${{ secrets.CF_BUCKET_PREVIEW }}/unraid-api/" \
+          OLD_FILES=$(aws s3 ls "s3://${{ secrets.CF_BUCKET_PREVIEW }}/${{ inputs.BUCKET_PATH }}/" \
             --endpoint-url ${{ secrets.CF_ENDPOINT }} --recursive | \
             grep -E "dynamix\.unraid\.net-[0-9]{4}\.[0-9]{2}\.[0-9]{2}\.[0-9]{4}\.txz" | \
             awk '{print $4}' || true)
           
-          DELETED_COUNT=0
+          DELETED_COUNT=0
+          FAILED_COUNT=0
           if [ -n "$OLD_FILES" ]; then
             while IFS= read -r file; do
               if [[ $file =~ ([0-9]{4}\.[0-9]{2}\.[0-9]{2})\.[0-9]{4}\.txz ]]; then
                 FILE_DATE="${BASH_REMATCH[1]}"
                 if [[ "$FILE_DATE" < "$CUTOFF_DATE" ]]; then
                   echo "Deleting old build: $(basename "$file")"
-                  aws s3 rm "s3://${{ secrets.CF_BUCKET_PREVIEW }}/${file}" \
-                    --endpoint-url ${{ secrets.CF_ENDPOINT }} || true
-                  ((DELETED_COUNT++))
+                  if aws s3 rm "s3://${{ secrets.CF_BUCKET_PREVIEW }}/${file}" \
+                    --endpoint-url ${{ secrets.CF_ENDPOINT }} >/dev/null 2>&1; then
+                    ((DELETED_COUNT++))
+                  else
+                    ((FAILED_COUNT++))
+                  fi
                 fi
               fi
             done <<< "$OLD_FILES"
           fi
           
-          echo "✅ Deleted ${DELETED_COUNT} old builds"
+          echo "✅ Deleted ${DELETED_COUNT} old builds"
+          if [ "$FAILED_COUNT" -gt 0 ]; then
+            echo "⚠️ Failed deletions: ${FAILED_COUNT}"
+          fi

195-221: Trim trailing spaces to satisfy YAML linting

Trailing spaces flagged at Lines 196, 200, 206, 221. Remove to keep CI/lint green.


201-209: Optional: prefer s3api + JMESPath over text parsing

aws s3 ls | grep | awk is brittle. aws s3api list-objects-v2 --prefix "${{ inputs.BUCKET_PATH }}/" --query would avoid format parsing. Keep as-is if you prefer simplicity.

scripts/cleanup-pr-builds.sh (3)

6-6: Harden shell: use -euo pipefail

Prevents silent failures and use of unset vars during cleanup.

-set -e
+set -euo pipefail

60-66: Add non-interactive mode for automation

Support a “yes” flag or env to skip prompt when running headless.

-# Confirmation prompt
-read -p "Are you sure you want to delete ALL these PR builds? (yes/no): " -r
-echo ""
-
-if [[ ! $REPLY =~ ^[Yy]es$ ]]; then
+# Confirmation prompt (skip with --yes or CONFIRM=yes)
+if [[ "${1:-}" == "--yes" || "${CONFIRM:-}" =~ ^[Yy]([eE][sS])?$ ]]; then
+  REPLY="yes"
+else
+  read -p "Are you sure you want to delete ALL these PR builds? (yes/no): " -r
+  echo ""
+fi
+if [[ ! ${REPLY:-} =~ ^[Yy]es$ ]]; then
     echo -e "${YELLOW}⚠️  Cleanup cancelled${NC}"
     exit 0
 fi

46-47: Directory detection is output-format dependent

Parsing aws s3 ls with grep "PRE PR" assumes AWS CLI’s human format. Consider aws s3api list-objects-v2 --delimiter '/' --prefix 'unraid-api/tag/PR' to list common prefixes robustly. OK to keep if you prefer simplicity.

scripts/cleanup-old-builds.sh (3)

6-6: Harden shell: use -euo pipefail

Avoids masked failures and unset var usage during deletions.

-set -e
+set -euo pipefail

109-117: Optional: allow non-interactive confirmation

Helpful for periodic cleanups; can be gated by env var to avoid breaking interactive usage.

-# Confirmation prompt
-read -p "Are you sure you want to delete these ${OLD_COUNT} old builds? (yes/no): " -r
-echo ""
-
-if [[ ! $REPLY =~ ^[Yy]es$ ]]; then
+# Confirmation prompt (skip with CONFIRM=yes)
+if [[ -z "${CONFIRM:-}" ]]; then
+  read -p "Are you sure you want to delete these ${OLD_COUNT} old builds? (yes/no): " -r
+  echo ""
+fi
+if [[ ! ${CONFIRM:-$REPLY} =~ ^[Yy]es$ ]]; then
     echo -e "${YELLOW}⚠️  Cleanup cancelled${NC}"
     exit 0
 fi

60-63: Prefer s3api over human parsing

aws s3 ls | awk '{print $4}' is fragile. aws s3api list-objects-v2 --prefix 'unraid-api/' --query 'Contents[?contains(Key, dynamix.unraid.net-)].Key' --output text is more robust. Optional.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between abc22bd and da43c39.

📒 Files selected for processing (4)
  • .github/workflows/build-plugin.yml (1 hunks)
  • .github/workflows/main.yml (1 hunks)
  • scripts/cleanup-old-builds.sh (1 hunks)
  • scripts/cleanup-pr-builds.sh (1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.37.1)
.github/workflows/build-plugin.yml

[error] 196-196: trailing spaces

(trailing-spaces)


[error] 200-200: trailing spaces

(trailing-spaces)


[error] 206-206: trailing spaces

(trailing-spaces)


[error] 221-221: trailing spaces

(trailing-spaces)

🔇 Additional comments (1)
.github/workflows/main.yml (1)

11-11: LGTM: conditional cancel-in-progress

Only cancels PR runs; keeps push workflows unaffected. Looks good.

@elibosley elibosley merged commit 88baddd into main Sep 9, 2025
16 checks passed
@elibosley elibosley deleted the chore/build-cleanup branch September 9, 2025 16:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant