build(deps): bump actions/cache from 5 to 6 #10
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: MemBrowse Memory Report | |
| on: | |
| pull_request: | |
| push: | |
| branches: | |
| - master | |
| - "releases/*" | |
| permissions: | |
| contents: read | |
| # Per-PR group so superseded PR pushes cancel; per-SHA on push so master | |
| # commits never share a group. A shared refs/heads/master group lets a burst | |
| # of pushes evict each other while pending (GitHub keeps only one pending run | |
| # per group), leaving a commit with no report and breaking the MemBrowse | |
| # parent chain for every commit that bases on it. | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| jobs: | |
| # Detect whether any source files (i.e. non-doc/CODEOWNERS) changed. | |
| # When only docs/CODEOWNERS change we skip the build and post an "identical" | |
| # MemBrowse report instead. | |
| changes-filter: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| source: ${{ steps.filter.outputs.source }} | |
| steps: | |
| # Shallow checkout; the base commit needed for the diff is fetched | |
| # explicitly below instead of cloning the repo's full history. | |
| - uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 2 | |
| # Detect whether any non-doc/CODEOWNERS source files changed. | |
| # Implemented with plain git instead of a third-party paths-filter | |
| # action, since Apache's GitHub Actions allowlist forbids actions that | |
| # aren't GitHub-created or explicitly permitted. | |
| - id: filter | |
| env: | |
| BASE_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }} | |
| HEAD_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} | |
| run: | | |
| # On the very first push to a branch, github.event.before is all-zeros. | |
| if [ -z "$BASE_SHA" ] || [ "$BASE_SHA" = "0000000000000000000000000000000000000000" ]; then | |
| echo "source=true" >> "$GITHUB_OUTPUT" | |
| echo "No usable base SHA; treating as source change." | |
| exit 0 | |
| fi | |
| # The shallow checkout may not contain BASE_SHA (multi-commit pushes, | |
| # long-lived PR branches). Fetch just that commit; fall back to a full | |
| # unshallow only if the targeted fetch fails. | |
| if ! git cat-file -e "$BASE_SHA^{commit}" 2>/dev/null; then | |
| git fetch --depth=1 origin "$BASE_SHA" 2>/dev/null \ | |
| || git fetch --unshallow origin 2>/dev/null \ | |
| || git fetch --unshallow 2>/dev/null || true | |
| fi | |
| changed=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA") | |
| echo "Changed files:" | |
| echo "$changed" | |
| # Drop paths that should NOT count as source changes; if anything | |
| # survives, real source changed. | |
| source=$(echo "$changed" | grep -vE \ | |
| -e '^AUTHORS$' \ | |
| -e '^CONTRIBUTING\.md$' \ | |
| -e '(^|/)CODEOWNERS$' \ | |
| -e '^Documentation/' \ | |
| -e '^tools/ci/docker/linux/' \ | |
| -e '^tools/codeowners/[^/]+$' \ | |
| || true) | |
| if [ -n "$source" ]; then | |
| echo "source=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "source=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| load-targets: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| matrix: ${{ steps.set-matrix.outputs.matrix }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - id: set-matrix | |
| run: echo "matrix=$(jq -c '.' .github/membrowse-targets.json)" >> $GITHUB_OUTPUT | |
| # Post an "identical" MemBrowse report when only docs/CODEOWNERS changed. | |
| # Only runs on push events (master/releases/tags) to keep the baseline | |
| # complete; PR events don't produce identical markers. | |
| identical: | |
| needs: [changes-filter, load-targets] | |
| if: needs.changes-filter.outputs.source == 'false' && github.event_name == 'push' | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: ${{ fromJson(needs.load-targets.outputs.matrix) }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 2 | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.11' | |
| - name: Install membrowse | |
| run: pip install --no-cache-dir membrowse | |
| - name: Upload identical - ${{ matrix.target_name }} | |
| env: | |
| MEMBROWSE_API_KEY: ${{ secrets.MEMBROWSE_API_KEY }} | |
| MEMBROWSE_API_URL: ${{ vars.MEMBROWSE_API_URL }} | |
| TARGET_NAME: ${{ matrix.target_name }} | |
| # Base on the previous branch tip, not the (often unreported mid-PR) | |
| # git parent. | |
| BEFORE_SHA: ${{ github.event.before }} | |
| run: | | |
| ARGS=(--upload --github | |
| --target-name "$TARGET_NAME" | |
| --api-key "$MEMBROWSE_API_KEY" | |
| --identical) | |
| if [ -n "$MEMBROWSE_API_URL" ]; then | |
| ARGS+=(--api-url "$MEMBROWSE_API_URL") | |
| fi | |
| # Override parent with previous tip; skip on branch creation (0s). | |
| if [ -n "$BEFORE_SHA" ] && [ "$BEFORE_SHA" != "0000000000000000000000000000000000000000" ]; then | |
| ARGS+=(--base-sha "$BEFORE_SHA") | |
| fi | |
| membrowse report "${ARGS[@]}" | |
| # Build target with debug symbols + linker map, then upload MemBrowse report. | |
| # Uses the NuttX CI Docker image so toolchains, kconfig-frontends, etc. are | |
| # already installed. | |
| analyze: | |
| needs: [changes-filter, load-targets] | |
| if: needs.changes-filter.outputs.source == 'true' | |
| runs-on: ubuntu-latest | |
| env: | |
| DOCKER_BUILDKIT: 1 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: ${{ fromJson(needs.load-targets.outputs.matrix) }} | |
| steps: | |
| - name: Checkout nuttx repo | |
| uses: actions/checkout@v7 | |
| with: | |
| path: sources/nuttx | |
| fetch-depth: 2 | |
| - name: Checkout nuttx-apps repo | |
| uses: actions/checkout@v7 | |
| with: | |
| repository: apache/nuttx-apps | |
| path: sources/apps | |
| fetch-depth: 1 | |
| - name: Docker Login | |
| uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Docker Pull | |
| run: docker pull ghcr.io/apache/nuttx/apache-nuttx-ci-linux | |
| - name: Build ${{ matrix.target_name }} | |
| uses: ./sources/nuttx/.github/actions/ci-container | |
| with: | |
| run: | | |
| git config --global --add safe.directory /github/workspace/sources/nuttx | |
| git config --global --add safe.directory /github/workspace/sources/apps | |
| cd /github/workspace/sources/nuttx | |
| ./tools/configure.sh -l ${{ matrix.board_config }} | |
| echo CONFIG_DEBUG_SYMBOLS=y >> .config | |
| echo CONFIG_DEBUG_LINK_MAP=y >> .config | |
| if [ -n "${{ matrix.config_overrides }}" ]; then | |
| kconfig-tweak ${{ matrix.config_overrides }} | |
| fi | |
| make olddefconfig | |
| # Preserve preprocessed linker scripts (.ld.tmp) so MemBrowse can | |
| # read them. Arch Makefiles delete these immediately after linking. | |
| find arch -name Makefile -exec sed -i '/DELFILE, $(addsuffix .tmp,$(ARCHSCRIPT))/d' {} + | |
| make -j$(nproc) | |
| # MemBrowse action runs from $GITHUB_WORKSPACE and discovers git via CWD, | |
| # but nuttx is checked out to sources/nuttx/ (so apps can sit beside it). | |
| # Expose the repo's .git at the workspace root so git metadata resolves. | |
| - name: Expose nuttx .git to workspace root | |
| run: ln -sfn sources/nuttx/.git .git | |
| - name: Prefix linker script paths | |
| id: ld | |
| run: | | |
| prefixed="" | |
| for p in ${{ matrix.ld }}; do | |
| prefixed="$prefixed sources/nuttx/$p" | |
| done | |
| paths=$(echo $prefixed | xargs) | |
| echo "paths=$paths" >> "$GITHUB_OUTPUT" | |
| echo "Resolved ld paths: [$paths]" | |
| for p in $paths; do | |
| if [ -e "$p" ]; then | |
| echo " OK $p ($(stat -c '%s bytes, owner=%U:%G' "$p" 2>/dev/null))" | |
| else | |
| echo " MISS $p" | |
| echo " ls dir:" | |
| ls -la "$(dirname "$p")" 2>&1 | head -30 | |
| fi | |
| done | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.11' | |
| - name: Install membrowse | |
| run: pip install --no-cache-dir membrowse | |
| - name: MemBrowse analysis - ${{ matrix.target_name }} | |
| env: | |
| MEMBROWSE_API_KEY: ${{ secrets.MEMBROWSE_API_KEY }} | |
| MEMBROWSE_API_URL: ${{ vars.MEMBROWSE_API_URL }} | |
| TARGET_NAME: ${{ matrix.target_name }} | |
| ELF: sources/nuttx/${{ matrix.elf }} | |
| LD_PATHS: ${{ steps.ld.outputs.paths }} | |
| MAP_FILE: ${{ matrix.map_file != '' && format('sources/nuttx/{0}', matrix.map_file) || '' }} | |
| LINKER_VARS: ${{ matrix.linker_vars }} | |
| # Push only: base on the previous branch tip, not the (often | |
| # unreported mid-PR) git parent. Empty on PRs (--github bases on the | |
| # PR target tip). | |
| BEFORE_SHA: ${{ github.event_name == 'push' && github.event.before || '' }} | |
| run: | | |
| set -o pipefail | |
| ARGS=("$ELF" "$LD_PATHS" | |
| --upload --github | |
| --target-name "$TARGET_NAME" | |
| --api-key "$MEMBROWSE_API_KEY") | |
| if [ -n "$MEMBROWSE_API_URL" ]; then | |
| ARGS+=(--api-url "$MEMBROWSE_API_URL") | |
| fi | |
| # Override parent with previous tip; skip on branch creation (0s). | |
| if [ -n "$BEFORE_SHA" ] && [ "$BEFORE_SHA" != "0000000000000000000000000000000000000000" ]; then | |
| ARGS+=(--base-sha "$BEFORE_SHA") | |
| fi | |
| if [ -n "$MAP_FILE" ]; then | |
| ARGS+=(--map-file "$MAP_FILE") | |
| fi | |
| if [ -n "$LINKER_VARS" ]; then | |
| set -f | |
| for var in $LINKER_VARS; do | |
| ARGS+=(--def "$var") | |
| done | |
| set +f | |
| fi | |
| membrowse --verbose INFO report "${ARGS[@]}" |