Skip to content

Conversation

@AnthonyRonning
Copy link
Contributor

@AnthonyRonning AnthonyRonning commented Jan 20, 2026

The nttld/setup-ndk local-cache option has a known bug where symlinks break after cache restore (see nttld/setup-ndk#547). This causes the NDK to be re-downloaded on every run despite caching attempts.

Changes:

  • Switch to manual caching with actions/cache which properly handles the NDK directory
  • Cache key is simple (Linux-ndk-r27c) since NDK content is static for a given version
  • Skip setup-ndk action entirely when cache hits

Expected behavior:

  • First run: Downloads NDK (~1.5GB), saves to cache
  • Subsequent runs: Restores from cache in seconds, skips download entirely

This should eliminate the 5-15 minute waits you've been seeing when Google's CDN is slow.

Summary by CodeRabbit

  • Chores
    • Added Android NDK caching and a cache-hit check in CI to reduce build times and improve release pipeline reliability.
    • Made NDK setup conditional on cache misses and standardized environment usage for the NDK to simplify CI behavior.

✏️ Tip: You can customize this high-level summary in your review settings.

The nttld/setup-ndk local-cache option has a known bug where symlinks
break after cache restore (see nttld/setup-ndk#547). This causes NDK
to be re-downloaded on every run despite caching.

Switch to manual caching with actions/cache which properly handles
the NDK directory. The cache key is simple (OS + NDK version) since
the NDK content is static.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
@coderabbitai
Copy link

coderabbitai bot commented Jan 20, 2026

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

The pull request adds Android NDK caching to two CI workflows (.github/workflows/android-build.yml and .github/workflows/release.yml), makes the Setup Android NDK step conditional on cache misses, and switches NDK path usage from a step output to a fixed path (/home/runner/.setup-ndk/r27c).

Changes

Cohort / File(s) Summary
CI Workflow NDK Caching
.github/workflows/android-build.yml, .github/workflows/release.yml
Add Android NDK cache restore/save steps with a cache-hit key; skip the Setup Android NDK step on cache hit; remove reliance on steps.setup-ndk.outputs.ndk-path and set NDK_HOME=/home/runner/.setup-ndk/r27c in the Rust build step.

Sequence Diagram(s)

sequenceDiagram
    participant GH as "GitHub Actions"
    participant Cache as "NDK Cache"
    participant Setup as "Setup Android NDK"
    participant Build as "Rust Build Step"

    GH->>Cache: restore ndk-cache key
    alt cache hit
        Cache-->>GH: cache hit
        GH->>Build: run build (NDK_HOME=/home/runner/.setup-ndk/r27c)
    else cache miss
        Cache-->>GH: cache miss
        GH->>Setup: install NDK r27c
        Setup-->>GH: NDK installed at /home/runner/.setup-ndk/r27c
        GH->>Build: run build (NDK_HOME=/home/runner/.setup-ndk/r27c)
        GH->>Cache: save ndk-cache
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

🐰 I found a cache beneath the log,
NDK dreams snugged in a tiny bog,
Skip the setup dance, hop straight to build,
Fixed path, steady steps—no longer chilled,
Hooray for faster runs! 🥕✨

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: replacing a broken local-cache approach with the standard actions/cache for Android NDK caching.

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


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

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Jan 20, 2026

Deploying maple with  Cloudflare Pages  Cloudflare Pages

Latest commit: aa851da
Status: ✅  Deploy successful!
Preview URL: https://084b35bf.maple-ca8.pages.dev
Branch Preview URL: https://fix-ndk-cache-manual.maple-ca8.pages.dev

View logs

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 20, 2026

Greptile Overview

Greptile Summary

Implemented manual NDK caching using actions/cache@v4 to work around symlink restoration bugs in nttld/setup-ndk's built-in caching.

Key Changes:

  • Added actions/cache step before NDK setup to manually cache /home/runner/.setup-ndk/r27c
  • Made NDK setup conditional (only runs on cache miss) to skip downloads when cache hits
  • Replaced dynamic NDK path output with hardcoded /home/runner/.setup-ndk/r27c path
  • Removed add-to-path: true option (PATH now set manually in build step)
  • Applied changes consistently across both android-build.yml and release.yml workflows

Minor Consideration:

  • The local-cache: true parameter remains in the NDK setup despite the PR description indicating this feature has bugs. Since the setup step now only runs on cache misses and actions/cache handles the actual caching, this parameter may be redundant.

Confidence Score: 4/5

  • Safe to merge with minimal risk - addresses documented NDK caching issue with established solution.
  • The implementation correctly uses actions/cache to work around the known symlink bug. The hardcoded path matches where setup-ndk installs NDK r27c. Minor concern about keeping local-cache: true but this won't cause issues since the step is conditionally skipped on cache hits.
  • No files require special attention - changes are straightforward CI/CD caching improvements.

Important Files Changed

Filename Overview
.github/workflows/android-build.yml Added manual NDK caching with actions/cache@v4 to work around symlink restoration issues, conditionally skips NDK download when cache hits.
.github/workflows/release.yml Applied same NDK caching strategy as android-build.yml to improve release pipeline performance.

Sequence Diagram

sequenceDiagram
    participant GHA as GitHub Actions
    participant Cache as actions/cache
    participant NDK as setup-ndk
    participant Build as Rust Build

    GHA->>Cache: Check for cached NDK at /home/runner/.setup-ndk/r27c
    alt Cache Hit
        Cache->>GHA: Restore NDK from cache
        Note over NDK: Setup NDK step skipped (if condition false)
        GHA->>Build: Use cached NDK at /home/runner/.setup-ndk/r27c
    else Cache Miss
        Cache->>GHA: No cache found
        GHA->>NDK: Run setup-ndk (download ~1.5GB)
        NDK->>GHA: NDK installed to /home/runner/.setup-ndk/r27c
        GHA->>Cache: Save NDK to cache
        GHA->>Build: Use newly installed NDK at /home/runner/.setup-ndk/r27c
    end
    Build->>Build: Export NDK_HOME and build Rust library
Loading

Without local-cache: true, setup-ndk puts NDK in /opt/hostedtoolcache/
instead of ~/.setup-ndk/r27c where the build expects it.
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

2 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

with:
ndk-version: r27c
add-to-path: true
local-cache: true
Copy link
Contributor

Choose a reason for hiding this comment

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

local-cache: true still enabled but PR description says this option has symlink bugs. Consider removing since you're using actions/cache now.

Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/android-build.yml
Line: 142:142

Comment:
`local-cache: true` still enabled but PR description says this option has symlink bugs. Consider removing since you're using `actions/cache` now.

How can I resolve this? If you propose a fix, please make it concise.

with:
ndk-version: r27c
add-to-path: true
local-cache: true
Copy link
Contributor

Choose a reason for hiding this comment

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

local-cache: true still enabled but PR description says this option has symlink bugs. Consider removing since you're using actions/cache now.

Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/release.yml
Line: 267:267

Comment:
`local-cache: true` still enabled but PR description says this option has symlink bugs. Consider removing since you're using `actions/cache` now.

How can I resolve this? If you propose a fix, please make it concise.

Copy link

@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

🤖 Fix all issues with AI agents
In @.github/workflows/release.yml:
- Around line 255-267: The workflow hardcodes the NDK install path and thus
mismatches the dynamic path returned by the setup action; update the cache and
environment usage to consume the setup action output instead: read the NDK path
from the setup action's output (steps.setup-ndk.outputs.ndk-path) returned by
uses: nttld/setup-ndk@v1 (the step currently referenced as setup-ndk), replace
the hardcoded /home/runner/.setup-ndk/r27c used in the actions/cache step (id:
ndk-cache) and any NDK-related env vars (NDK_HOME, ANDROID_NDK_HOME, etc.) with
that output reference so the cache key/path and environment variables
consistently use ${{ steps.setup-ndk.outputs.ndk-path }}.
♻️ Duplicate comments (1)
.github/workflows/android-build.yml (1)

187-190: Consider DRY-ing NDK path/version (same as release.yml).
The same drift/sanity-check suggestion applies here too.

🧹 Nitpick comments (1)
.github/workflows/release.yml (1)

312-316: Centralize NDK_VERSION/NDK_HOME and add a quick sanity check.
The hard-coded path appears in multiple places; defining NDK_VERSION/NDK_HOME once reduces drift when upgrading and a quick test -x guard makes cache corruption fail fast.

♻️ Proposed refactor
 jobs:
   android-rust-build:
     needs: android-frontend-build
     runs-on: ubuntu-latest-8-cores
+    env:
+      NDK_VERSION: r27c
+      NDK_HOME: /home/runner/.setup-ndk/r27c
@@
       - name: Cache Android NDK
         uses: actions/cache@v4
         id: ndk-cache
         with:
-          path: /home/runner/.setup-ndk/r27c
-          key: ${{ runner.os }}-ndk-r27c
+          path: ${{ env.NDK_HOME }}
+          key: ${{ runner.os }}-ndk-${{ env.NDK_VERSION }}
@@
       - name: Setup Android NDK
         if: steps.ndk-cache.outputs.cache-hit != 'true'
         uses: nttld/setup-ndk@v1
         with:
-          ndk-version: r27c
+          ndk-version: ${{ env.NDK_VERSION }}
@@
       - name: Build Rust library (${{ matrix.rust_target }})
         run: |
-          export NDK_HOME=/home/runner/.setup-ndk/r27c
+          export NDK_HOME=${NDK_HOME}
+          test -x "$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/clang" || { echo "NDK missing/corrupt"; exit 1; }
           export PATH=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH

Comment on lines 255 to 267
- name: Cache Android NDK
uses: actions/cache@v4
id: ndk-cache
with:
path: /home/runner/.setup-ndk/r27c
key: ${{ runner.os }}-ndk-r27c

- name: Setup Android NDK
if: steps.ndk-cache.outputs.cache-hit != 'true'
uses: nttld/setup-ndk@v1
id: setup-ndk
with:
ndk-version: r27c
add-to-path: true
local-cache: true

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

nttld/setup-ndk v1 default install directory path

💡 Result:

nttld/setup-ndk@v1 does not expose a single fixed global path — it downloads/extracts the requested NDK for the runner/workflow and returns the actual install location as the action output steps..outputs.ndk-path. Use that output (examples show ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}). [1]

Source: action marketplace page / usage examples. [1]


🌐 Web query:

GitHub Actions cache size limit per repository

💡 Result:

Short answer

  • Default per-repository cache quota: 10 GB. [1][2]
  • Unused caches (not accessed) are eligible for eviction after 7 days; when the repo exceeds its quota, least‑recently‑used caches are evicted. [1][3]
  • You can raise the per‑repo limit (paid, admin-configurable / pay‑as‑you‑go). Enterprise/org admins can set higher maxima — Enterprise Cloud docs note configurable limits up to 10,000 GB per repo (and GitHub announced support for >10 GB with billing). [2][3]

Sources

  • actions/cache README (cache limits & eviction). [1]
  • GitHub changelog: cache can exceed 10 GB / pay-as-you-go (Nov 20, 2025). [2]
  • GitHub Docs — managing Actions cache settings / Enterprise Cloud limits (configurable maxes, eviction/retention). [3]

🏁 Script executed:

# Check if there are any other references to NDK paths in the workflow
rg "ndk|NDK" .github/workflows/release.yml -n

Repository: OpenSecretCloud/Maple

Length of output: 1264


NDK cache and setup need critical fixes to work reliably.

The nttld/setup-ndk@v1 action returns the NDK install path dynamically via steps.ndk-cache.outputs.ndk-path — it does not guarantee installation to /home/runner/.setup-ndk/r27c. The workflow currently hardcodes this path in both the cache configuration (line 259) and environment variables (lines 315–328), creating a mismatch: the cache may miss if the action installs elsewhere, and the hardcoded NDK_HOME may point to the wrong location.

Fix: Capture the NDK path from the setup action output and use it consistently. Replace hardcoded paths with ${{ steps.setup-ndk.outputs.ndk-path }}.

GitHub Actions cache limits (10 GB default per repo) are not a concern for the NDK size.

🤖 Prompt for AI Agents
In @.github/workflows/release.yml around lines 255 - 267, The workflow hardcodes
the NDK install path and thus mismatches the dynamic path returned by the setup
action; update the cache and environment usage to consume the setup action
output instead: read the NDK path from the setup action's output
(steps.setup-ndk.outputs.ndk-path) returned by uses: nttld/setup-ndk@v1 (the
step currently referenced as setup-ndk), replace the hardcoded
/home/runner/.setup-ndk/r27c used in the actions/cache step (id: ndk-cache) and
any NDK-related env vars (NDK_HOME, ANDROID_NDK_HOME, etc.) with that output
reference so the cache key/path and environment variables consistently use ${{
steps.setup-ndk.outputs.ndk-path }}.

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