Skip to content

chore: replace peaceiris/actions-gh-pages and dorny/paths-filter with native git/shell#109

Open
Copilot wants to merge 12 commits into
mainfrom
copilot/audit-gh-actions
Open

chore: replace peaceiris/actions-gh-pages and dorny/paths-filter with native git/shell#109
Copilot wants to merge 12 commits into
mainfrom
copilot/audit-gh-actions

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 27, 2026

  • deploy.sh: Add EXIT trap for guaranteed worktree cleanup; add rsync --delete with --exclude=.git (protects worktree ref) + --exclude=previews/ (protects preview dirs) for root deploys; move .nojekyll creation to AFTER rsync (prevents --delete from removing it)
  • detect-changes.yml: Add .github/actions/**/*.sh/yml/yaml, .github/scripts/**/*.sh, .github/workflows/**/*.yml/yaml glob patterns to filter
  • preview.yml: Change concurrency group to "pages" (shared with deploy.yml) + cancel-in-progress: false to prevent cancelling in-flight production deploys
  • unit-tests.yml: Check both needs.test.result AND needs.changes.result in status step
  • tests/gh-pages-deploy.test.sh: Add || exit 1 to cd "${TMPWORK}"; add root-deploy stale-file removal and previews-preservation tests (24 tests total, all pass)
  • filter.js: Switch to NUL-delimited -z git output (git ls-files -z, git diff --name-only -z, split on \0); add fail-fast guard for empty filtersMap
  • tests/paths-filter.test.js: Update all getChangedFiles/main tests for NUL output + -z flag; replace empty-filters test with fail-fast guard test; reset process.exitCode in beforeEach (448 tests, all pass)
  • docs/LEARNINGS.md: Add PR log entry
  • 448 Jest tests pass, filter.js 100%/100%/100%/100%, 24 shell tests pass

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 27, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds two repo-local composite actions (gh-pages-deploy, paths-filter), a reusable detect-changes workflow, supporting scripts and tests, and updates multiple workflows to use the new actions and gate jobs via the detect-changes workflow.

Changes

Cohort / File(s) Summary
gh-pages deploy action
./.github/actions/gh-pages-deploy/action.yml, ./.github/actions/gh-pages-deploy/deploy.sh
New composite action + bash deploy script. Reads INPUT_* variables, embeds token into remote URL when provided, manages git worktree/orphan branch for publish branch, rsyncs publish_dir → worktree with excludes/destination handling, handles .nojekyll, commits/pushes, and force-removes the worktree on exit.
paths-filter action
./.github/actions/paths-filter/action.yml, ./.github/actions/paths-filter/filter.js
New composite action + Node worker. Parses YAML filters, computes diff base from GitHub context, obtains changed files (git diff/git ls-files), converts globs→regex, evaluates filters, emits per-filter booleans and optional file lists, and writes outputs to GITHUB_OUTPUT/stdout.
Detect-change scripts & workflow
./.github/scripts/detect-changes.sh, ./.github/workflows/detect-changes.yml
Bash helper and reusable workflow_call workflow that select base SHA per event, invoke local paths-filter, expose code output for gating CI, and include safe fallbacks on git failures.
Workflow updates
./.github/workflows/deploy.yml, ./.github/workflows/preview.yml, ./.github/workflows/preview-cleanup.yml, ./.github/workflows/e2e-tests.yml, ./.github/workflows/unit-tests.yml
Replace external actions with local gh-pages-deploy, delegate path gating to reusable detect-changes.yml, add concurrency for previews, adjust publish_dir, commit_message, and expand exclude_assets semantics.
Tests & CI config
package.json, tests/detect-changes.test.sh, tests/gh-pages-deploy.test.sh, tests/paths-filter.test.js
Add shell and Jest tests covering deploy and path-filter behavior; add test:shell script; include .github/actions/**/*.js in coverage and add per-file coverage thresholds for filter.js.
Docs
docs/LEARNINGS.md
Document CI guardrails: static composite action outputs, worktree cleanup, rsync behavior, preferring native git/rsync/diff patterns, and rules for passing GitHub context to shell steps.

Sequence Diagram(s)

sequenceDiagram
  participant Workflow as "Workflow (caller)"
  participant Action as "Composite Action\n(gh-pages-deploy)"
  participant Script as "deploy.sh"
  participant Git as "Local Git\n(worktree)"
  participant Remote as "Git Remote\n(origin)"
  Workflow->>Action: invoke with inputs/env
  Action->>Script: execute deploy.sh (INPUT_* env)
  Script->>Git: fetch/check publish branch, create or switch worktree/orphan
  Script->>Git: compute destination path, clear if needed
  Script->>Git: rsync publish_dir → worktree (apply excludes/destination_dir)
  Script->>Git: stage changes, commit if changes
  Script->>Remote: push publish_branch (token-embedded URL)
  Script->>Git: git worktree remove --force (cleanup)
  Script-->>Workflow: exit status / logs
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

I pity the fool who doesn't read this!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 73.91% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning The PR description is a checklist of implementation details without a proper summary section explaining the problem and solution. Add a Summary section describing what problem this PR solves and how the native git/shell replacements improve the workflow. Reorganize the checklist into a Changes section with discrete items.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: replacing external GitHub Actions with native git/shell implementations.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch copilot/audit-gh-actions

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

github-actions Bot added a commit that referenced this pull request Apr 27, 2026
github-actions Bot added a commit that referenced this pull request Apr 27, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 27, 2026

👁️ PR Preview

🚀 Open Preview

Deployed from commit 406f305 · Updates on every push to this PR
(Preview is removed automatically when the PR is closed.)

Screenshots

Desktop Mobile
Desktop Mobile

@nitrocode nitrocode marked this pull request as ready for review April 27, 2026 12:12
github-actions Bot added a commit that referenced this pull request Apr 27, 2026
github-actions Bot added a commit that referenced this pull request Apr 27, 2026
github-actions Bot added a commit that referenced this pull request Apr 27, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 27, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (07b4e8b) to head (406f305).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##              main      #109    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files            1         2     +1     
  Lines          263       382   +119     
  Branches       113       159    +46     
==========================================
+ Hits           263       382   +119     
Flag Coverage Δ
unit 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
.github/actions/paths-filter/filter.js 100.00% <100.00%> (ø)

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 07b4e8b...406f305. Read the comment docs.

🚀 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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
docs/LEARNINGS.md (1)

105-118: ⚠️ Potential issue | 🟡 Minor

Replace the #— placeholders in the categorised learnings table.

I pity the fool who leaves the source PR blank when the PR number is already known. A5, A6, S4, and S5 lose traceability in the table future agents are supposed to scan first. As per coding guidelines, "Follow the learning pattern in docs/LEARNINGS.md — add entries with category headers, concise descriptions, links to PRs, and update the Categorised Learnings tables by topic".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/LEARNINGS.md` around lines 105 - 118, The table rows for A5, A6, S4 and
S5 in docs/LEARNINGS.md currently have "#—" placeholders in the "Source PR"
column; replace each placeholder with the actual PR identifier (e.g. "PR `#1234`"
or a GitHub PR link) that introduced the learning so the entries are traceable,
keeping the existing table format and category headers; specifically update the
rows for A5 (Composite action outputs), A6 (git worktree cleanup + rsync
mtime/size note), S4 (actions vs third-party actions recommendation) and S5
(pass GitHub context via env), ensuring each Source PR cell contains the PR
number or link consistent with other table entries and follow the documented
learning pattern.
.github/workflows/unit-tests.yml (1)

57-64: ⚠️ Potential issue | 🟠 Major

Don't let the status job hide a broken changes job.

I pity the fool who reports green when change detection already blew up. Right now this step only checks needs.test.result, so a failure in the reusable workflow or local paths-filter action turns test into skipped and this status still exits 0.

Suggested fix
-          if [[ "${{ needs.test.result }}" == "failure" ]]; then
+          if [[ "${{ needs.changes.result }}" == "failure" || "${{ needs.test.result }}" == "failure" ]]; then
             echo "Unit tests failed"
             exit 1
           fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/unit-tests.yml around lines 57 - 64, The report step
currently only inspects needs.test.result and can report success when the
reusable 'changes' job (or paths-filter) failed; update the "Report status" step
to check the result of both dependent jobs (e.g., needs.test.result and
needs.changes.result) and exit non‑zero if any existing dependency's result is
not "success" (treat "failure" or other non-success values as failure), ensuring
the workflow fails when the changes job or test job fails.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/actions/gh-pages-deploy/deploy.sh:
- Around line 72-95: The current logic only clears stale files when DEPLOY is to
a subdirectory (DESTINATION_DIR set) and leaves root deploys intact; change it
so when KEEP_FILES != "true" we remove stale files for root deploys too while
preserving previews/; do this by removing the DESTINATION_DIR check and either
(a) always using rsync with --delete when KEEP_FILES != "true" and adding a
protect exclude "--exclude=previews/" into the RSYNC_EXCLUDES array, or (b) if
keeping the find-based removal, run the find ... -delete unconditionally when
KEEP_FILES != "true" but skip deleting the previews/ directory (e.g., exclude
"${DEST}/previews" from deletion). Update the rsync invocation (rsync -a ...) to
include the --delete flag when KEEP_FILES != "true" and ensure RSYNC_EXCLUDES
contains "--exclude=previews/" so previews/ is preserved; keep existing symbols:
KEEP_FILES, DESTINATION_DIR, DEST, RSYNC_EXCLUDES, EXCLUDE_ASSETS, PUBLISH_DIR,
WORKTREE_DIR, and the .nojekyll touch logic unchanged.

In @.github/workflows/detect-changes.yml:
- Around line 70-76: Update the "filters" code patterns in detect-changes.yml's
filters block so CI-only changes are detected: add glob entries for YAML
workflow files (*.yml, *.yaml), shell scripts (*.sh), and the
actions/reusable-workflow locations (e.g., add patterns matching the actions
directory and workflow files) alongside the existing
JS/TS/CSS/tests/package*.json globs so changes to CI workflows and action
scripts no longer resolve to code=false.

In @.github/workflows/preview.yml:
- Around line 7-10: The preview workflow's concurrency group uses
"pages-preview-${{ github.event.number }}" which doesn't coordinate with the
production deploy's concurrency group ("pages"), allowing simultaneous pushes to
gh-pages; update the concurrency.group value in this file from
"pages-preview-${{ github.event.number }}" to "pages" so all workflows that push
gh-pages share the same lock (leave cancel-in-progress behavior as appropriate),
and if you still need per-PR cancellation preserve that logic at the job level
or elsewhere that does not perform the branch push.

In `@docs/LEARNINGS.md`:
- Around line 150-155: Update the PR log entry in docs/LEARNINGS.md: replace the
placeholder "PR #—" with "PR `#109`", change the title to "chore: replace
peaceiris/actions-gh-pages and dorny/paths-filter with native git/shell", and
correct the learning pointer from "(→ A1, S5)" to "(→ A5, A6)"; ensure the entry
follows the repository learning pattern by adding appropriate category headers,
a concise description, and a link to PR `#109`, and then update the Categorised
Learnings tables by topic to include this entry (verify related files referenced
like .github/actions/paths-filter/action.yml and
.github/actions/gh-pages-deploy/deploy.sh are noted if required).

In `@tests/gh-pages-deploy.test.sh`:
- Around line 104-106: The subshell that starts with "(" runs cd "${TMPWORK}"
then env; if the cd fails the script continues in the wrong directory — update
the subshell's cd invocation (the line containing cd "${TMPWORK}" inside the "("
... ")" block) to fail fast by appending a short-circuit exit (i.e., change the
cd command to include "|| exit 1") so the subshell stops immediately when the
temp worktree can't be entered.

---

Outside diff comments:
In @.github/workflows/unit-tests.yml:
- Around line 57-64: The report step currently only inspects needs.test.result
and can report success when the reusable 'changes' job (or paths-filter) failed;
update the "Report status" step to check the result of both dependent jobs
(e.g., needs.test.result and needs.changes.result) and exit non‑zero if any
existing dependency's result is not "success" (treat "failure" or other
non-success values as failure), ensuring the workflow fails when the changes job
or test job fails.

In `@docs/LEARNINGS.md`:
- Around line 105-118: The table rows for A5, A6, S4 and S5 in docs/LEARNINGS.md
currently have "#—" placeholders in the "Source PR" column; replace each
placeholder with the actual PR identifier (e.g. "PR `#1234`" or a GitHub PR link)
that introduced the learning so the entries are traceable, keeping the existing
table format and category headers; specifically update the rows for A5
(Composite action outputs), A6 (git worktree cleanup + rsync mtime/size note),
S4 (actions vs third-party actions recommendation) and S5 (pass GitHub context
via env), ensuring each Source PR cell contains the PR number or link consistent
with other table entries and follow the documented learning pattern.
🪄 Autofix (Beta)

❌ Autofix failed (check again to retry)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 15760f86-87a2-4049-b9f2-c4674fe3c0d9

📥 Commits

Reviewing files that changed from the base of the PR and between a794491 and 88eaee1.

📒 Files selected for processing (16)
  • .github/actions/gh-pages-deploy/action.yml
  • .github/actions/gh-pages-deploy/deploy.sh
  • .github/actions/paths-filter/action.yml
  • .github/actions/paths-filter/filter.js
  • .github/scripts/detect-changes.sh
  • .github/workflows/deploy.yml
  • .github/workflows/detect-changes.yml
  • .github/workflows/e2e-tests.yml
  • .github/workflows/preview-cleanup.yml
  • .github/workflows/preview.yml
  • .github/workflows/unit-tests.yml
  • docs/LEARNINGS.md
  • package.json
  • tests/detect-changes.test.sh
  • tests/gh-pages-deploy.test.sh
  • tests/paths-filter.test.js

Comment thread .github/actions/gh-pages-deploy/deploy.sh Outdated
Comment thread .github/workflows/detect-changes.yml
Comment thread .github/workflows/preview.yml Outdated
Comment thread docs/LEARNINGS.md Outdated
Comment thread tests/gh-pages-deploy.test.sh
Copilot AI and others added 2 commits April 27, 2026 12:32
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
docs/LEARNINGS.md (1)

117-118: ⚠️ Potential issue | 🟡 Minor

I pity the fool who left placeholder PR numbers in the Security learnings table!

S4 and S5 both say "PR #—" when they oughta say PR #109! Don't be a fool - fix those placeholders!

💪 Proposed fix
-| S4 | Prefer `actions/` (GitHub's official org) over third-party organisations for GitHub Actions steps. `peaceiris/actions-gh-pages` can be replaced with native `git worktree` + `rsync` shell commands; `dorny/paths-filter` can be replaced with a `git diff --name-only` shell step. | #— |
-| S5 | Always pass GitHub context values to shell scripts via `env:` vars (e.g. `GH_SHA: ${{ github.sha }}`), never by interpolating `${{ }}` directly inside `run:`. Inline interpolation allows expression injection if an attacker controls the context value. | #— |
+| S4 | Prefer `actions/` (GitHub's official org) over third-party organisations for GitHub Actions steps. `peaceiris/actions-gh-pages` can be replaced with native `git worktree` + `rsync` shell commands; `dorny/paths-filter` can be replaced with a `git diff --name-only` shell step. | `#109` |
+| S5 | Always pass GitHub context values to shell scripts via `env:` vars (e.g. `GH_SHA: ${{ github.sha }}`), never by interpolating `${{ }}` directly inside `run:`. Inline interpolation allows expression injection if an attacker controls the context value. | `#109` |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/LEARNINGS.md` around lines 117 - 118, Update the Security learnings
table entries labeled "S4" and "S5" to replace the placeholder PR reference "PR
#—" with the correct PR number "PR `#109`"; specifically edit the table cells
containing the S4 and S5 rows so the rightmost column reads "PR `#109`" (or uses
inline code formatting `#109` if consistent with the table style).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/LEARNINGS.md`:
- Around line 105-106: Update the PR reference placeholders in the LEARNINGS
table entries A5 and A6 to the actual PR number: replace "PR #—" with "PR `#109`"
for both rows so the table correctly cites PR `#109` instead of the placeholder;
target the two table cells containing A5 and A6 text in docs/LEARNINGS.md.
- Around line 150-182: Replace the four placeholder "PR #—" tokens in the four
PR log entries with the correct PR number "#109" (search for the four
occurrences of the literal string "PR #—" in the LEARNINGS.md PR entries) and
update the incorrect learning pointer "(→ A1, S5)" to "(→ A5, A6)" (look for
that pointer on the PR entry describing composite actions). Also ensure each
updated PR entry follows the project's learning entry pattern (category headers,
concise description, link to PR `#109`) and update the Categorised Learnings
tables to include these corrected entries under the appropriate topics.

---

Duplicate comments:
In `@docs/LEARNINGS.md`:
- Around line 117-118: Update the Security learnings table entries labeled "S4"
and "S5" to replace the placeholder PR reference "PR #—" with the correct PR
number "PR `#109`"; specifically edit the table cells containing the S4 and S5
rows so the rightmost column reads "PR `#109`" (or uses inline code formatting
`#109` if consistent with the table style).
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 56736e0f-ee11-44e3-8bf4-aa020acd57b1

📥 Commits

Reviewing files that changed from the base of the PR and between 88eaee1 and 8eb3f1a.

📒 Files selected for processing (5)
  • .github/actions/paths-filter/filter.js
  • .github/workflows/deploy.yml
  • docs/LEARNINGS.md
  • package.json
  • tests/paths-filter.test.js
✅ Files skipped from review due to trivial changes (1)
  • .github/actions/paths-filter/filter.js
🚧 Files skipped from review as they are similar to previous changes (3)
  • .github/workflows/deploy.yml
  • package.json
  • tests/paths-filter.test.js

Comment thread docs/LEARNINGS.md Outdated
Comment thread docs/LEARNINGS.md Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
.github/actions/gh-pages-deploy/deploy.sh (1)

75-83: ⚠️ Potential issue | 🟠 Major

Don’t let root deploys keep ghost files alive, fool.

Line [78] only clears stale content for subdirectory deploys. Root deploys can keep deleted assets indefinitely, which leaves old production files publicly served.

Proposed fix
-# When keep_files is false and deploying to a subdirectory, clear stale content
-# so deleted files don't linger.  Root deployments always preserve other content
-# (e.g. the previews/ directory) regardless of keep_files.
-if [[ "${KEEP_FILES}" != "true" && -n "${DESTINATION_DIR}" ]]; then
-  # Suppress errors (|| true): a non-zero exit here means DEST is already empty
-  # or a file is already gone — both are harmless.  Genuine failures (e.g.
-  # permission errors on the runner) will surface at the rsync or git-add step.
-  find "${DEST}" -mindepth 1 -delete 2>/dev/null || true
-fi
+# When keep_files is false, remove stale files before sync.
+# Preserve previews/ for root deploys.
+if [[ "${KEEP_FILES}" != "true" ]]; then
+  if [[ -z "${DESTINATION_DIR}" ]]; then
+    RSYNC_EXCLUDES+=("--exclude=previews/")
+    RSYNC_DELETE=(--delete)
+  else
+    find "${DEST}" -mindepth 1 -delete 2>/dev/null || true
+  fi
+fi
@@
-rsync -a ${RSYNC_EXCLUDES[@]+"${RSYNC_EXCLUDES[@]}"} "${PUBLISH_DIR%/}/" "${DEST}/"
+rsync -a ${RSYNC_DELETE[@]+"${RSYNC_DELETE[@]}"} \
+  ${RSYNC_EXCLUDES[@]+"${RSYNC_EXCLUDES[@]}"} \
+  "${PUBLISH_DIR%/}/" "${DEST}/"

Also applies to: 101-101

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/actions/gh-pages-deploy/deploy.sh around lines 75 - 83, The
conditional currently only clears stale files when KEEP_FILES != "true" and
DESTINATION_DIR is set, leaving root deployments to accumulate stale files;
change the logic so that whenever KEEP_FILES != "true" the script runs the find
"${DEST}" -mindepth 1 -delete 2>/dev/null || true cleanup regardless of
DESTINATION_DIR. Update the block using KEEP_FILES/DESTINATION_DIR/DEST (and the
duplicate cleanup block later that mirrors this logic) so root deploys also
purge deleted assets, keeping the same error suppression (|| true) behavior.
🧹 Nitpick comments (2)
.github/workflows/preview-cleanup.yml (1)

23-25: Line 23 says “positive integer,” but the regex still allows 0.

If you want strict alignment, use ^[1-9][0-9]*$ (or update the comment to “non-negative integer”).

Suggested tweak
-          # Validate PR_NUMBER is a positive integer to guard against malformed
+          # Validate PR_NUMBER is a positive integer to guard against malformed
           # context values that could produce an unexpected directory path.
-          if [[ ! "${PR_NUMBER}" =~ ^[0-9]+$ ]]; then
+          if [[ ! "${PR_NUMBER}" =~ ^[1-9][0-9]*$ ]]; then
             echo "Unexpected PR_NUMBER value: '${PR_NUMBER}' — aborting cleanup" >&2
             exit 1
           fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/preview-cleanup.yml around lines 23 - 25, The comment and
regex disagree: the check for PR_NUMBER currently allows zero but says “positive
integer”; update the validation in the PR_NUMBER check so it enforces a strictly
positive integer by replacing the regex with one that disallows 0 (e.g., use the
pattern ^[1-9][0-9]*$) or, alternatively, keep the current regex and change the
comment to say “non-negative integer”; locate the PR_NUMBER validation block in
the preview-cleanup.yml workflow (the if [[ ! "${PR_NUMBER}" =~ ... ]]) and
apply the chosen fix so the comment and validation match.
.github/actions/gh-pages-deploy/deploy.sh (1)

32-33: Set an EXIT trap for worktree cleanup, fool.

Line [117] cleanup runs only on the happy path. With set -e, failures before the end can leave a registered worktree behind and trip later invocations in the same job.

Proposed hardening
 WORKTREE_DIR="$(mktemp -d)"
+REPO_ROOT="$(git rev-parse --show-toplevel)"
+
+cleanup() {
+  set +e
+  cd "${REPO_ROOT}" || return
+  git worktree remove --force "${WORKTREE_DIR}" 2>/dev/null || rm -rf "${WORKTREE_DIR}"
+}
+trap cleanup EXIT
@@
-# Unregister and remove the worktree to avoid conflicts when the action is
-# called multiple times within the same job (e.g. a preview workflow that
-# deploys the site and then uploads screenshots).
-cd -
-git worktree remove --force "${WORKTREE_DIR}" 2>/dev/null || rm -rf "${WORKTREE_DIR}"
+# Cleanup is handled by trap on all exit paths.

Also applies to: 113-117

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/actions/gh-pages-deploy/deploy.sh around lines 32 - 33, The script
creates a temporary WORKTREE_DIR (variable WORKTREE_DIR="$(mktemp -d)") but only
removes it on the happy path (cleanup at lines ~113-117); add a trap 'EXIT' that
always removes the worktree if set and non-empty (and unregisters it if
necessary) so failures under set -e cannot leave the worktree behind; update the
cleanup logic referenced around the existing cleanup function/name to be
idempotent and referenced by the trap, e.g., define a cleanup function that
checks WORKTREE_DIR and runs git worktree remove/unregister and rm -rf, then
register it with 'trap cleanup EXIT'.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/actions/paths-filter/filter.js:
- Around line 272-273: After calling parseFilters(filtersYaml) (the filtersMap
variable), add a fail-fast guard that detects an empty or malformed
INPUT_FILTERS parse result (e.g., filtersMap is null/undefined or
Object.keys(filtersMap).length === 0) and immediately fails the action with a
clear error message (using core.setFailed or throwing) so the script doesn't
continue and emit only changes={} without per-filter outputs; place this check
right after the parseFilters(filtersYaml) line to ensure parse failures are
explicit and per-filter outputs are not silently omitted.
- Around line 231-245: The current spawnSync calls that run 'git ls-files' and
'git diff --name-only' use r.stdout.trim().split('\n') which strips
leading/trailing whitespace from valid filenames; update both spawnSync
invocations to pass the -z flag (i.e., ['ls-files','-z'] and
['diff','-z','--name-only', base, sha]) and replace the
r.stdout.trim().split('\n').filter(Boolean) handling with
r.stdout.split('\0').filter(Boolean) so filenames are NUL-delimited and
whitespace is preserved.

---

Duplicate comments:
In @.github/actions/gh-pages-deploy/deploy.sh:
- Around line 75-83: The conditional currently only clears stale files when
KEEP_FILES != "true" and DESTINATION_DIR is set, leaving root deployments to
accumulate stale files; change the logic so that whenever KEEP_FILES != "true"
the script runs the find "${DEST}" -mindepth 1 -delete 2>/dev/null || true
cleanup regardless of DESTINATION_DIR. Update the block using
KEEP_FILES/DESTINATION_DIR/DEST (and the duplicate cleanup block later that
mirrors this logic) so root deploys also purge deleted assets, keeping the same
error suppression (|| true) behavior.

---

Nitpick comments:
In @.github/actions/gh-pages-deploy/deploy.sh:
- Around line 32-33: The script creates a temporary WORKTREE_DIR (variable
WORKTREE_DIR="$(mktemp -d)") but only removes it on the happy path (cleanup at
lines ~113-117); add a trap 'EXIT' that always removes the worktree if set and
non-empty (and unregisters it if necessary) so failures under set -e cannot
leave the worktree behind; update the cleanup logic referenced around the
existing cleanup function/name to be idempotent and referenced by the trap,
e.g., define a cleanup function that checks WORKTREE_DIR and runs git worktree
remove/unregister and rm -rf, then register it with 'trap cleanup EXIT'.

In @.github/workflows/preview-cleanup.yml:
- Around line 23-25: The comment and regex disagree: the check for PR_NUMBER
currently allows zero but says “positive integer”; update the validation in the
PR_NUMBER check so it enforces a strictly positive integer by replacing the
regex with one that disallows 0 (e.g., use the pattern ^[1-9][0-9]*$) or,
alternatively, keep the current regex and change the comment to say
“non-negative integer”; locate the PR_NUMBER validation block in the
preview-cleanup.yml workflow (the if [[ ! "${PR_NUMBER}" =~ ... ]]) and apply
the chosen fix so the comment and validation match.
🪄 Autofix (Beta)

❌ Autofix failed (check again to retry)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1b4cd099-4148-4314-9ac7-7da209f8d873

📥 Commits

Reviewing files that changed from the base of the PR and between 8eb3f1a and 669de03.

📒 Files selected for processing (4)
  • .github/actions/gh-pages-deploy/deploy.sh
  • .github/actions/paths-filter/filter.js
  • .github/workflows/detect-changes.yml
  • .github/workflows/preview-cleanup.yml
✅ Files skipped from review due to trivial changes (1)
  • .github/workflows/detect-changes.yml

Comment thread .github/actions/paths-filter/filter.js Outdated
Comment thread .github/actions/paths-filter/filter.js
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 27, 2026

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

⛔ CodeRabbit does not have permission to push changes to this repository. Please ensure CodeRabbit has Contents: Read and write permission.

Fixed 1 file(s) based on 2 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
github-actions Bot added a commit that referenced this pull request Apr 27, 2026
github-actions Bot added a commit that referenced this pull request Apr 27, 2026
github-actions Bot added a commit that referenced this pull request Apr 27, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/LEARNINGS.md`:
- Around line 117-118: Update the Security & Supply Chain table entries S4 and
S5 in docs/LEARNINGS.md by replacing the placeholder PR reference "#—" with the
correct PR number "#109" for both rows (the lines containing "S4 | Prefer
`actions/`..." and "S5 | Always pass GitHub context..."); ensure the format
matches the other table entries (category header, concise description, link/PR
column) so the table remains consistent with the Architecture table changes
already made.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c46dc931-26a0-4ca5-8b3e-2eaaa9684381

📥 Commits

Reviewing files that changed from the base of the PR and between 669de03 and 82cbcab.

📒 Files selected for processing (1)
  • docs/LEARNINGS.md

Comment thread docs/LEARNINGS.md Outdated
Signed-off-by: RB <7775707+nitrocode@users.noreply.github.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 27, 2026

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 1 file(s) based on 1 unresolved review comment.

Files modified:

  • docs/LEARNINGS.md

Commit: 44882ef981edbd9cb90ef32362665cddece4b513

The changes have been pushed to the copilot/audit-gh-actions branch.

Time taken: 1m 35s

github-actions Bot added a commit that referenced this pull request Apr 27, 2026
github-actions Bot added a commit that referenced this pull request Apr 27, 2026
github-actions Bot added a commit that referenced this pull request Apr 27, 2026
Fixed 1 file(s) based on 1 unresolved review comment.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
docs/LEARNINGS.md (1)

118-119: ⚠️ Potential issue | 🟡 Minor

Replace remaining #— placeholders with the actual PR reference.

I pity the fool who leaves unresolved placeholders in the Source PR column — update both rows to #109 so these learnings are traceable and consistent with the rest of this update.

💪 Proposed fix
-| S4 | Prefer `actions/` (GitHub's official org) over third-party organisations for GitHub Actions steps. `peaceiris/actions-gh-pages` can be replaced with native `git worktree` + `rsync` shell commands; `dorny/paths-filter` can be replaced with a `git diff --name-only` shell step. | #— |
-| S5 | Always pass GitHub context values to shell scripts via `env:` vars (e.g. `GH_SHA: ${{ github.sha }}`), never by interpolating `${{ }}` directly inside `run:`. Inline interpolation allows expression injection if an attacker controls the context value. | #— |
+| S4 | Prefer `actions/` (GitHub's official org) over third-party organisations for GitHub Actions steps. `peaceiris/actions-gh-pages` can be replaced with native `git worktree` + `rsync` shell commands; `dorny/paths-filter` can be replaced with a `git diff --name-only` shell step. | `#109` |
+| S5 | Always pass GitHub context values to shell scripts via `env:` vars (e.g. `GH_SHA: ${{ github.sha }}`), never by interpolating `${{ }}` directly inside `run:`. Inline interpolation allows expression injection if an attacker controls the context value. | `#109` |

As per coding guidelines, "Follow the learning pattern in docs/LEARNINGS.md — add entries with category headers, concise descriptions, links to PRs, and update the Categorised Learnings tables by topic".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/LEARNINGS.md` around lines 118 - 119, Update the two table rows for
learning items S4 and S5 in docs/LEARNINGS.md by replacing the placeholder
Source PR column values `#—` with the actual PR reference `#109`; locate the
rows identified by the symbols "S4" and "S5" and set their third-column value to
`#109` so the entries are traceable and consistent with the rest of the
document.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/LEARNINGS.md`:
- Line 151: Replace the PR log heading string "PR `#109` refactor: replace
third-party actions with native git worktree and diff" in docs/LEARNINGS.md with
the actual Conventional Commit title: "chore: replace peaceiris/actions-gh-pages
and dorny/paths-filter with native git/shell" so the entry exactly matches the
PR metadata and aids traceability.

---

Duplicate comments:
In `@docs/LEARNINGS.md`:
- Around line 118-119: Update the two table rows for learning items S4 and S5 in
docs/LEARNINGS.md by replacing the placeholder Source PR column values `#—` with
the actual PR reference `#109`; locate the rows identified by the symbols "S4"
and "S5" and set their third-column value to `#109` so the entries are traceable
and consistent with the rest of the document.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8eebc9c6-960f-45ec-9bb5-a9b014b2acbf

📥 Commits

Reviewing files that changed from the base of the PR and between 82cbcab and a6a85a7.

📒 Files selected for processing (1)
  • docs/LEARNINGS.md

Comment thread docs/LEARNINGS.md Outdated
Signed-off-by: RB <7775707+nitrocode@users.noreply.github.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 27, 2026

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 1 file(s) based on 1 unresolved review comment.

Files modified:

  • docs/LEARNINGS.md

Commit: 51b7ae0fa88e06a76aacaf1de92a0893e07b77c1

The changes have been pushed to the copilot/audit-gh-actions branch.

Time taken: 1m 42s

github-actions Bot added a commit that referenced this pull request Apr 27, 2026
github-actions Bot added a commit that referenced this pull request Apr 27, 2026
github-actions Bot added a commit that referenced this pull request Apr 27, 2026
Fixed 1 file(s) based on 1 unresolved review comment.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
github-actions Bot added a commit that referenced this pull request Apr 27, 2026
github-actions Bot added a commit that referenced this pull request Apr 27, 2026
github-actions Bot added a commit that referenced this pull request Apr 27, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 27, 2026

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

⛔ CodeRabbit does not have permission to push changes to this repository. Please ensure CodeRabbit has Contents: Read and write permission.

@nitrocode
Copy link
Copy Markdown
Owner

@coderabbitai apply

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 28, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

I need to check what specific suggestion you're asking me to apply, fool! Let me look at the PR review comments right quick!


🏁 Script executed:

#!/bin/bash
# Fetch review comments by coderabbitai on PR `#109`
gh pr view 109 --repo nitrocode/token-deathclock --json reviews,reviewDecision,comments
echo "---"
gh api repos/nitrocode/token-deathclock/pulls/109/comments --jq '.[] | select(.user.login == "coderabbitai") | {id: .id, path: .path, line: .line, body: .body[0:500]}'
echo "---"
gh api repos/nitrocode/token-deathclock/issues/109/comments --jq '.[] | select(.user.login == "coderabbitai") | {id: .id, body: .body[0:500]}'

Length of output: 80737


@nitrocode: I hear ya, fool! Let me round up ALL the unresolved review comments and plan the fixes! I pity the fool who leaves these issues unaddressed! 💪

Applying all unresolved CodeRabbit review comments on PR #109

Here's what I'm fixing, sucka:

  1. deploy.sh — root deploys skip stale file cleanup + no EXIT trap for worktree
  2. detect-changes.yml — missing YAML/shell glob patterns
  3. preview.yml — concurrency group doesn't coordinate with production
  4. unit-tests.yml — status job ignores changes job failure
  5. preview-cleanup.yml — regex allows 0 but says "positive integer"
  6. docs/LEARNINGS.md — placeholder #— in A5, A6, S4, S5 + wrong PR log title/pointer
  7. filter.js — no fail-fast guard for empty INPUT_FILTERS; git output not NUL-delimited
  8. tests/gh-pages-deploy.test.shcd without || exit 1

🏁 Script executed:

#!/bin/bash
cat -n .github/actions/gh-pages-deploy/deploy.sh

Length of output: 6002


🏁 Script executed:

#!/bin/bash
cat -n .github/workflows/detect-changes.yml

Length of output: 4057


🏁 Script executed:

#!/bin/bash
cat -n .github/workflows/preview.yml

Length of output: 6136


🏁 Script executed:

#!/bin/bash
cat -n .github/workflows/unit-tests.yml

Length of output: 2111


🏁 Script executed:

#!/bin/bash
cat -n .github/workflows/preview-cleanup.yml

Length of output: 1510


🏁 Script executed:

#!/bin/bash
sed -n '95,195p' docs/LEARNINGS.md | cat -n

Length of output: 10538


🏁 Script executed:

#!/bin/bash
sed -n '220,290p' .github/actions/paths-filter/filter.js | cat -n

Length of output: 3322


🏁 Script executed:

#!/bin/bash
sed -n '95,120p' tests/gh-pages-deploy.test.sh | cat -n

Length of output: 925


I got everything I need, fool! Now let me plan ALL the fixes! I pity the fool who leaves these unresolved! 💪

Applying all unresolved CodeRabbit comments

  • Fix deploy.sh: EXIT trap + root-deploy stale-file cleanup via rsync --delete
  • Fix detect-changes.yml: add YAML/shell/action globs to filters
  • Fix preview.yml: share concurrency group "pages" with production deploy
  • Fix unit-tests.yml: check both changes and test job results in status step
  • Fix preview-cleanup.yml: enforce strictly-positive integer regex
  • Fix docs/LEARNINGS.md: correct learning pointer in PR #109 log entry
  • Fix filter.js: NUL-delimited git output + fail-fast guard for empty filters parse
  • Fix tests/gh-pages-deploy.test.sh: cd || exit 1 in subshell

🧠 Learnings used
Learnt from: CR
Repo: nitrocode/token-deathclock PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-27T00:20:01.920Z
Learning: Applies to .github/workflows/preview.yml : Every pull request automatically receives a preview URL at `https://nitrocode.github.io/token-deathclock/previews/pr-{number}/` via the `preview.yml` workflow; previews are auto-cleaned when the PR closes

Failed to handle agent chat message. Please try again.

github-actions Bot added a commit that referenced this pull request May 5, 2026
github-actions Bot added a commit that referenced this pull request May 5, 2026
github-actions Bot added a commit that referenced this pull request May 5, 2026
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.

2 participants