Skip to content

Production-readiness cleanup: package fixes, site hardening, tests & CI - #10

Merged
nathanialhenniges merged 13 commits into
mainfrom
claude/homebrew-tap-cleanup-21dcf5
Jul 26, 2026
Merged

nathanialhenniges merged 13 commits into
mainfrom
claude/homebrew-tap-cleanup-21dcf5

Conversation

@nathanialhenniges

@nathanialhenniges nathanialhenniges commented Jul 24, 2026

Copy link
Copy Markdown
Member

Production-readiness pass over the tap: fixes shipped package bugs, hardens the
site build (security + reliability), server-renders detail pages, overhauls the
test suite, and consolidates CI so untested output can't deploy.

P0 — package correctness

  • iconwolf: correct v0.4.0 SHA-256; macOS-only + Apple-Silicon-only
    (depends_on :macos + arch: :arm64, before platform blocks); nested
    on_macos/on_arm; test asserts version.to_s; README template updated.
  • wolfwave: bump to 2.0.1; add verified: (homepage on a different host);
    depends_on macos: :tahoe; trim desc to <=80 chars.

P1 — deps, tests, CI

  • vitest 3.2.7 + patched transitive deps; npm audit = 0 vulnerabilities.
  • Tests build into an isolated temp dir, derive metadata from .rb, add cask
    validation, negative-field checks, unresolved-placeholder scan.
  • macOS CI job: brew style/readall/audit --strict --online/livecheck, real
    artifact-checksum verification, install smoke. Weekly release-freshness cron.
  • CI/deploy consolidated: build+test once, deploy the exact tested artifact,
    deploy gated on test+brew success. Actions SHA-pinned. ShellCheck + npm audit.

P1 — site security & reliability

  • Escaping hardened (no release JSON in <script>; name escaped in title/meta;
    U+2028/2029; URL scheme allowlist). Hostile-input regression tests.
  • Fetch: timeouts + retries, tag with/without v, pagination, STRICT/OFFLINE,
    Tailwind via npx --no-install.
  • Detail pages server-rendered; work with JS disabled (JS only enhances).

P1 — dedup

  • Kept consolidated detail-template; .rb = source of truth; README tables
    validated; stability rules guarded by a bash<->JS parity test.

P2 — a11y & maintainability

  • Search dialog: close button, focus-trap cycling, combobox/listbox ARIA,
    live-region, focus restore. Resilient clipboard/localStorage. Python 3 dep documented.

Verification

  • npm test -> 104 passed; npm audit -> 0 vulns; shellcheck clean; strict+offline
    builds leave no placeholders and server-render essential content.
  • brew checks + install smoke run on the macOS CI job.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Documentation pages now include server-rendered package details, caveats, version history, and install commands.
    • Search includes improved keyboard navigation, screen-reader announcements, accessible controls, and safer links.
    • Added automated checks for release freshness and download checksums.
  • Updates

    • Updated WolfWave to version 2.0.1 and refreshed IconWolf macOS ARM support.
    • Expanded documentation for local site builds and formula creation.
  • Bug Fixes

    • Improved theme persistence and clipboard copying in restricted browser environments.
    • Strengthened protection against unsafe links and malformed metadata.

nathanialhenniges and others added 9 commits July 23, 2026 13:46
- Update the v0.4.0 SHA-256 to the correct checksum.
- Declare the formula macOS-only and Apple-Silicon-only via depends_on
  :macos and depends_on arch: :arm64, placed before the platform blocks.
- Replace the inline Hardware::CPU.arm? conditional with nested
  on_macos/on_arm DSL blocks.
- Assert against version.to_s in the test instead of a literal "0.4.0".
- Mirror the dependency/architecture structure in the README formula
  template.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ds_on

- Update cask to version 2.0.1 with its SHA-256 (based on the
  origin/wolfwave-v2.0.1 bump).
- Add verified: "github.com/MrDemonWolf/wolfwave/" to the download URL
  since the homepage (mrdemonwolf.github.io) is on a different domain.
- Replace the deprecated depends_on macos: ">= :tahoe" with the
  supported depends_on macos: :tahoe.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Bump vitest to ^3.2.7 (resolved 3.2.7).
- Refresh package-lock.json; resolve advisories in vite, rollup, postcss,
  undici, picomatch, and esbuild via compatible non-breaking upgrades.
- npm audit now reports 0 vulnerabilities.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Security & reliability:
- Route release-history data through server-side escaping and HTML-escape
  the item name in <title>/<meta>/breadcrumb; add U+2028/U+2029 handling to
  json_escape (bash-3.2-safe octal) so no untrusted value can break out of a
  <script> block.
- Add a safe_url() scheme allowlist (http/https/mailto) for homepage and
  release-notes links.
- fetch_releases now uses curl connect/read timeouts + bounded retries,
  matches release tags with or without a leading "v", and paginates.
- Honor OFFLINE=1 (skip network) and STRICT_RELEASES/CI (fail rather than
  silently publish pages with version history removed).
- Run Tailwind via `npx --no-install` so the build never downloads a package.

Server-rendering:
- Render name, version, description, install command, homepage, caveats,
  stability, and the full version-history table into HTML at build time via
  new template placeholders. Detail pages are now fully useful with
  JavaScript disabled; the inline script only enhances (search/copy/theme/
  active-section tracking).
- Add an OUT_DIR knob so builds can target an isolated directory.

Also resolve the lone ShellCheck warning and document the Python 3 / offline
build requirements in the README.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Search dialog: visible close button, combobox/listbox semantics
  (role, aria-expanded, aria-activedescendant, aria-selected), an
  aria-live result-count announcer, and a real focus trap that cycles
  through every control instead of forcing focus back to the input.
  Focus still restores to the trigger on close.
- escapeHtml also neutralizes U+2028/U+2029; add a safeUrl() scheme
  allowlist used for search-result hrefs.
- Clipboard writes feature-detect navigator.clipboard and fall back to
  execCommand without throwing; theme localStorage reads/writes are
  wrapped so private-mode contexts don't break theme init.
- Remove the now-dead initDetailPage/stabilityBadge client renderer
  (content is server-rendered); detectStability stays as the tested
  reference classifier.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Homebrew audits description length; the previous 85-char desc would fail
brew audit --strict. Trim to 75 chars and update the README cask table.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- runBuild() now builds into an isolated temp dir (never reuses or deletes
  a user's _site) and runs OFFLINE for deterministic, network-free tests;
  bump vitest hookTimeout to match the build time.
- Derive expected metadata from Formula/*.rb and Casks/*.rb instead of
  hard-coding package names and versions; data-drive the build-output and
  html-content suites.
- Assert essential detail-page content is server-rendered (present before
  any script runs) and that NO {{...}} placeholder survives in any page.
- Add cask-validation.test.js (mirrors formula validation, incl. the
  verified-url rule) and validation-negative.test.js (missing/invalid
  required fields are detected).
- Add xss.test.js: builds a throwaway tap from a hostile formula and
  asserts </script> breakouts, javascript: URLs, and U+2028/U+2029 are
  neutralized in the output and embedded JSON.
- Add stability-parity.test.js: runs the same fixtures through the real
  bash detect_stability and JS detectStability and asserts they agree,
  preventing drift between the two implementations.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a test that fails when a README formula/cask row is missing or its
version/description drifts from the Formula/*.rb or Casks/*.rb source of
truth, keeping the hand-maintained tables honest.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Consolidate build/test/deploy into one workflow: the site is built and
  tested once, uploaded as the Pages artifact, and the deploy job (gated on
  both test and brew jobs succeeding, main pushes only) deploys that exact
  artifact. Removes the separate deploy-site.yml that could publish an
  untested, independently-rebuilt site.
- Build runs strict in CI (CI=true), so a GitHub API failure fails the run
  instead of silently shipping pages without version history.
- Add ShellCheck and `npm audit --audit-level=high` steps.
- New macos-latest brew job: brew style, readall, audit --strict --online
  (formulae + casks), livecheck, a real artifact-checksum verification
  (scripts/verify-checksums.sh downloads each asset and compares sha256),
  and a formula install/test smoke check.
- Pin every action to a full commit SHA with a version comment.
- Add a weekly scheduled release-freshness workflow
  (scripts/check-release-freshness.mjs) that flags packages behind their
  latest GitHub release.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@nathanialhenniges, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 47 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 97fd5666-41f3-4de9-999d-02163471bd98

📥 Commits

Reviewing files that changed from the base of the PR and between 62db118 and 7f7a93b.

📒 Files selected for processing (4)
  • .github/workflows/ci.yml
  • Casks/wolfwave.rb
  • Formula/iconwolf.rb
  • README.md

Walkthrough

The PR consolidates CI and Pages deployment, adds release freshness and checksum validation, server-renders documentation pages, improves search accessibility and safety, updates package metadata, and broadens automated site and package validation.

Changes

Site and package validation

Layer / File(s) Summary
Server-rendered site generation
scripts/build-site.sh, site/detail-template.html
Release history, detail metadata, caveats, version rows, escaping, and URL validation are rendered during the build.
Accessible client-side interactions
site/shared.js, site/partials/search-modal.html
Search ARIA state, announcements, focus trapping, clipboard fallback, safe URLs, and resilient theme storage are added.
Isolated builds and data-driven coverage
tests/*, vitest.config.js, package.json
Tests build into temporary directories and validate all package pages, metadata, placeholders, accessibility, XSS handling, stability parity, and invalid inputs.
CI, release checks, and package metadata
.github/workflows/*, scripts/check-release-freshness.mjs, scripts/verify-checksums.sh, Formula/iconwolf.rb, Casks/wolfwave.rb, README.md
CI adds Homebrew, checksum, Pages, and freshness checks while package metadata and contributor documentation are updated.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CI as GitHub Actions CI
  participant Build as build-site.sh
  participant API as GitHub Releases API
  participant Pages as GitHub Pages
  CI->>Build: Run strict site build
  Build->>API: Fetch release history
  API-->>Build: Return release metadata
  Build-->>CI: Produce tested Pages artifact
  CI->>Pages: Deploy artifact after test and brew jobs succeed
Loading

Possibly related PRs

Poem

A bunny hops through builds so bright,
Pages bloom from code at night.
Safe links twinkle, searches sing,
Fresh releases check each thing.
CI drums a steady tune—
Carrots for the pipeline moon!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 69.49% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main themes of package fixes, site hardening, tests, and CI changes.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/homebrew-tap-cleanup-21dcf5

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@nathanialhenniges nathanialhenniges changed the title claude/homebrew tap cleanup 21dcf5 Production-readiness cleanup: package fixes, site hardening, tests & CI Jul 24, 2026
nathanialhenniges and others added 3 commits July 24, 2026 04:35
brew style <tap> also lints shell scripts under the tap with Homebrew's
shfmt/shellcheck style (prefers [[ ]] and ${var}), which failed on the build
tooling. Point brew style at the .rb files so it validates the packages it is
meant to; build/CI scripts are already covered by the ShellCheck step.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- iconwolf: order symbol deps (:macos, arch:) before the named "node" dep
  per FormulaAudit/DependencyOrder.
- wolfwave: alphabetize the zap trash array per Cask/ArrayAlphabetization.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
FormulaAudit/DependencyOrder wants `depends_on arch:` before
`depends_on :macos`. Reorder and mirror the README template.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (4)
tests/xss.test.js (1)

50-57: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicates extractJSON instead of reusing it.

This re-implements the same non-greedy const data = ({...}); extraction already exported as extractJSON in helpers.js (which also asserts the match isn't null with a clear failure message). Reusing it here avoids two copies of the same fragile regex drifting apart.

♻️ Suggested fix
-import { buildFixtureTap } from "./helpers.js";
+import { buildFixtureTap, extractJSON } from "./helpers.js";
...
-    const match = html.match(/const data = (\{.*?\});/s);
-    expect(match).not.toBeNull();
-    const data = JSON.parse(match[1]);
+    const data = extractJSON(html, "data");
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/xss.test.js` around lines 50 - 57, Update the “keeps the embedded
search index parseable as JSON” test to reuse the exported extractJSON helper
from helpers.js instead of duplicating the regex extraction and null assertion;
keep the existing JSON and formulae.desc assertions unchanged.
tests/helpers.js (2)

28-40: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

No cleanup of mkdtempSync directories.

runBuild, callBashFunction, and buildFixtureTap each create a temp directory but never remove it. Over a full CI run this can accumulate disk usage (especially buildFixtureTap, which recursively copies scripts/ and site/ per call). Consider an afterAll/afterEach cleanup (e.g. rmSync(dir, { recursive: true, force: true })) for at least the fixture-tap and bash-function temp dirs.

Also applies to: 169-178, 185-208

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/helpers.js` around lines 28 - 40, Clean up temporary directories
created by runBuild, callBashFunction, and buildFixtureTap by tracking each
directory for the appropriate test scope and removing it with recursive, forced
deletion in afterAll or afterEach hooks. Ensure cleanup runs even when tests
fail and preserves reuse of runBuild’s cached build output within its scope.

156-162: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Fragile brace-matching extraction of shared source.

Both loadSharedFunction and callBashFunction extract a function body via a non-greedy regex ending at the first \n}/\n\} at column 0. This is a reasonable approach to avoid drift from site/shared.js/scripts/build-site.sh, but it silently mis-extracts (truncates early) if the target function ever contains a nested block whose closing brace lands at column 0 — a subtle, hard-to-diagnose failure mode. Static analysis also flags the new Function() eval and the non-literal RegExp construction; in this context the inputs are hardcoded test-call literals, not attacker-controlled, so the practical risk is low, but the extraction fragility itself is worth a short comment noting the column-0-brace assumption so future refactors of shared.js/build-site.sh don't break it silently.

Also applies to: 169-178

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/helpers.js` around lines 156 - 162, Document the extraction assumption
in both loadSharedFunction and callBashFunction: their regexes require the
target function’s closing brace to appear at column 0 and can truncate on an
earlier matching brace. Add a concise maintenance comment near each extraction
explaining this constraint and the required alignment with site/shared.js and
scripts/build-site.sh, without changing the existing extraction behavior.

Source: Linters/SAST tools

tests/build-output.test.js (1)

83-102: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Raw .rb values compared against HTML-escaped output.

render_detail_page in scripts/build-site.sh HTML-escapes desc, homepage, etc. before embedding them, but these tests compare the raw .rb field value directly against the escaped HTML via toContain. This works only while current values are free of &, <, >, ". Any future desc containing one of these (e.g. "Sync & backup") will fail this assertion even though the page renders correctly. html-content.test.js avoids this by comparing against Cheerio's decoded .text().

♻️ Suggested approach
-    expect(html).toContain(f.desc);
+    expect(html).toContain(f.desc.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"));

Or better, switch these assertions to loadHTML(...) + Cheerio selectors like the equivalent checks in tests/html-content.test.js.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/build-output.test.js` around lines 83 - 102, Update the metadata
assertions in the Formula and Cask test cases to parse each generated page with
loadHTML and validate decoded element text through Cheerio selectors, matching
the approach in html-content.test.js. Replace raw toContain checks for escaped
fields such as desc, homepage, license, and appName while preserving the
existing metadata coverage.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Formula/iconwolf.rb`:
- Around line 7-9: Reorder the dependency declarations in the formula so the
macOS and ARM64 platform constraints appear before depends_on "node". Preserve
all existing dependencies and constraints unchanged.

In `@scripts/check-release-freshness.mjs`:
- Around line 48-54: Update the release-fetch logic in the freshness-check loop
to use an explicit release-selection policy by enumerating releases when
prereleases must be considered, filtering the results accordingly, and selecting
the intended release rather than relying on /releases/latest. Add a bounded
request timeout via AbortSignal.timeout(...) to the fetch call, while preserving
the existing non-OK error handling and freshness comparison flow.

In `@scripts/verify-checksums.sh`:
- Around line 16-20: Update the checksum validation logic around the version,
URL, and SHA256 assignments in the script to use braced variable expansions and
Bash [[ ... ]] conditionals, then apply brew style --fix to resolve any
remaining formatting violations before checksum verification runs.

---

Nitpick comments:
In `@tests/build-output.test.js`:
- Around line 83-102: Update the metadata assertions in the Formula and Cask
test cases to parse each generated page with loadHTML and validate decoded
element text through Cheerio selectors, matching the approach in
html-content.test.js. Replace raw toContain checks for escaped fields such as
desc, homepage, license, and appName while preserving the existing metadata
coverage.

In `@tests/helpers.js`:
- Around line 28-40: Clean up temporary directories created by runBuild,
callBashFunction, and buildFixtureTap by tracking each directory for the
appropriate test scope and removing it with recursive, forced deletion in
afterAll or afterEach hooks. Ensure cleanup runs even when tests fail and
preserves reuse of runBuild’s cached build output within its scope.
- Around line 156-162: Document the extraction assumption in both
loadSharedFunction and callBashFunction: their regexes require the target
function’s closing brace to appear at column 0 and can truncate on an earlier
matching brace. Add a concise maintenance comment near each extraction
explaining this constraint and the required alignment with site/shared.js and
scripts/build-site.sh, without changing the existing extraction behavior.

In `@tests/xss.test.js`:
- Around line 50-57: Update the “keeps the embedded search index parseable as
JSON” test to reuse the exported extractJSON helper from helpers.js instead of
duplicating the regex extraction and null assertion; keep the existing JSON and
formulae.desc assertions unchanged.
🪄 Autofix (Beta)

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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: db35222c-81d4-4805-b1e8-5a6af5e2972e

📥 Commits

Reviewing files that changed from the base of the PR and between 54c6484 and 62db118.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (22)
  • .github/workflows/ci.yml
  • .github/workflows/deploy-site.yml
  • .github/workflows/release-freshness.yml
  • Casks/wolfwave.rb
  • Formula/iconwolf.rb
  • README.md
  • package.json
  • scripts/build-site.sh
  • scripts/check-release-freshness.mjs
  • scripts/verify-checksums.sh
  • site/detail-template.html
  • site/partials/search-modal.html
  • site/shared.js
  • tests/build-output.test.js
  • tests/cask-validation.test.js
  • tests/helpers.js
  • tests/html-content.test.js
  • tests/readme-tables.test.js
  • tests/stability-parity.test.js
  • tests/validation-negative.test.js
  • tests/xss.test.js
  • vitest.config.js
💤 Files with no reviewable changes (1)
  • .github/workflows/deploy-site.yml

Comment thread Formula/iconwolf.rb Outdated
Comment on lines +48 to +54
const r = await fetch(`https://api.github.com/repos/${it.repo}/releases/latest`, { headers });
if (!r.ok) {
console.log(`! ${it.name}: GitHub API ${r.status} for ${it.repo}`);
errors++;
continue;
}
const latest = norm((await r.json()).tag_name);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Tracked files matching script:"
git ls-files | grep -F 'scripts/check-release-freshness.mjs' || true

if [ -f scripts/check-release-freshness.mjs ]; then
  echo
  echo "Outline/structure:"
  ast-grep outline scripts/check-release-freshness.mjs || true
  echo
  echo "Relevant lines:"
  cat -n scripts/check-release-freshness.mjs | sed -n '1,160p'
fi

echo
echo "Search for related config/release-freshness references:"
rg -n "check-release-freshness|release-freshness|releases/latest|AbortSignal|timeout" -S . || true

echo
echo "Node availability/version:"
node --version 2>/dev/null || true

Repository: MrDemonWolf/homebrew-den

Length of output: 4044


🌐 Web query:

GitHub REST API releases /owner/repo/releases/latest excludes prerelease documentation

💡 Result:

The GitHub REST API endpoint GET /repos/{owner}/{repo}/releases/latest specifically retrieves the most recent non-prerelease, non-draft release [1][2]. According to official GitHub documentation, this endpoint explicitly excludes prerelease and draft releases from being returned [1][3]. The release considered "latest" is determined by the created_at attribute, which corresponds to the date of the commit associated with the release, rather than the date it was published [1][2]. Additionally, GitHub documentation notes that draft and prerelease versions cannot be programmatically set as the "latest" release for a repository [3]. If a user manually marks a prerelease version as the "latest" via the GitHub web interface, it may appear as such, but the REST API's /latest endpoint is designed to filter these out in favor of the most recent stable (non-prerelease) release [1][2][4].

Citations:


Make release selection explicit and bound the request.

/releases/latest only returns the newest non-draft, non-prerelease release; enumerate releases if the check should include prereleases or respect an explicit policy. Also add a timeout, e.g. AbortSignal.timeout(...), so an unreachable API does not keep the workflow waiting.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/check-release-freshness.mjs` around lines 48 - 54, Update the
release-fetch logic in the freshness-check loop to use an explicit
release-selection policy by enumerating releases when prereleases must be
considered, filtering the results accordingly, and selecting the intended
release rather than relying on /releases/latest. Add a bounded request timeout
via AbortSignal.timeout(...) to the fetch call, while preserving the existing
non-OK error handling and freshness comparison flow.

Comment on lines +16 to +20
version=$(field "$rb" version)
url=$(field "$rb" url)
sha256=$(field "$rb" sha256)
if [ -z "$url" ] || [ -z "$sha256" ]; then
echo "-- skip $(basename "$rb") (no url/sha256)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Fix the shell style violations blocking Homebrew validation.

brew style currently fails before checksum verification runs. Brace variable expansions and use [[ ... ]]; then run brew style --fix for the remaining formatting changes.

Proposed fix
-  version=$(field "$rb" version)
-  url=$(field "$rb" url)
-  sha256=$(field "$rb" sha256)
-  if [ -z "$url" ] || [ -z "$sha256" ]; then
-    echo "-- skip $(basename "$rb") (no url/sha256)"
+  version="$(field "${rb}" version)"
+  url="$(field "${rb}" url)"
+  sha256="$(field "${rb}" sha256)"
+  if [[ -z "${url}" || -z "${sha256}" ]]; then
+    echo "-- skip $(basename "${rb}") (no url/sha256)"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
version=$(field "$rb" version)
url=$(field "$rb" url)
sha256=$(field "$rb" sha256)
if [ -z "$url" ] || [ -z "$sha256" ]; then
echo "-- skip $(basename "$rb") (no url/sha256)"
version="$(field "${rb}" version)"
url="$(field "${rb}" url)"
sha256="$(field "${rb}" sha256)"
if [[ -z "${url}" || -z "${sha256}" ]]; then
echo "-- skip $(basename "${rb}") (no url/sha256)"
🧰 Tools
🪛 GitHub Actions: CI / 1_Homebrew validation.txt

[warning] 16-41: ShellCheck reported multiple style issues (SC2250 and SC2292: Prefer [[ ]] over [ ] for tests in Bash/Ksh/Busybox) in /opt/homebrew/Library/Taps/mrdemonwolf/homebrew-den/scripts/verify-checksums.sh.

🪛 GitHub Check: Homebrew validation

[failure] 19-19:
Prefer putting braces around variable references even when not strictly required.


[failure] 19-19:
Prefer [[ ]] over [ ] for tests in Bash/Ksh/Busybox.


[failure] 18-18:
Prefer putting braces around variable references even when not strictly required.


[failure] 17-17:
Prefer putting braces around variable references even when not strictly required.


[failure] 16-16:
Prefer putting braces around variable references even when not strictly required.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/verify-checksums.sh` around lines 16 - 20, Update the checksum
validation logic around the version, URL, and SHA256 assignments in the script
to use braced variable expansions and Bash [[ ... ]] conditionals, then apply
brew style --fix to resolve any remaining formatting violations before checksum
verification runs.

Sources: Linters/SAST tools, Pipeline failures

A url/sha256 nested only inside on_macos/on_arm leaves the formula with no
stable url when Homebrew loads it in other OS/arch contexts, so brew readall
rejects it as invalid. Since only an Apple-Silicon macOS binary is published,
move url + sha256 to the top level and rely on depends_on arch: :arm64 +
depends_on :macos to restrict installation. Update the README template to
match (nested per-platform blocks are for formulae with multiple binaries).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@nathanialhenniges
nathanialhenniges merged commit 7f7a93b into main Jul 26, 2026
5 checks passed
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