Skip to main content

Setup

Add MemBrowse to your existing GitHub Actions workflow. If you already build your firmware in CI, this takes just a few minutes.

AI-assisted setup

If you use Claude Code, install the MemBrowse plugin and run the integration skill:

/plugin marketplace add membrowse/membrowse-action
/plugin install membrowse
/membrowse:membrowse-integrate

This will analyze your build system, verify your ELF outputs and linker scripts, create membrowse-targets.json, and set up all GitHub Actions workflows.

Prerequisites

  • GitHub repository with your firmware project
  • ELF file output from your build
  • Linker script(s) defining memory regions (optional but recommended for accurate region tracking)
  • MemBrowse API key (from Project Settings)

Step 1: Add API Key to Secrets

  1. Go to your GitHub repository
  2. Navigate to Settings > Secrets and variables > Actions
  3. Click New repository secret
  4. Name: MEMBROWSE_API_KEY
  5. Value: Your API key from Project Settings

Step 2: Update Workflow Triggers and Permissions

Your workflow needs to run on both pushes to main and pull requests. Add pull-requests: write so MemBrowse can post PR comments, and a concurrency group to cancel outdated runs when new commits are pushed:

on:
pull_request:
push:
branches:
- main

permissions:
contents: read
pull-requests: write

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

Also make sure your checkout step uses fetch-depth: 0 so MemBrowse can read the full git history (commit messages, branch names, etc.):

      - uses: actions/checkout@v5
with:
fetch-depth: 0

Step 3: Add MemBrowse Steps

Add these steps after your build step. The continue-on-error: true ensures that a MemBrowse issue never blocks your CI pipeline:

      - name: Analyze memory
id: analyze
continue-on-error: true
uses: membrowse/membrowse-action@v1
with:
elf: build/firmware.elf # Path to your ELF file
ld: linker.ld # Path to your linker script(s)
target_name: my-target # Name for this build target
api_key: ${{ secrets.MEMBROWSE_API_KEY }}

- name: Post PR comment
if: ${{ steps.analyze.outcome == 'success' && github.event_name == 'pull_request' }}
uses: membrowse/membrowse-action/comment-action@v1
with:
json_files: ${{ steps.analyze.outputs.report_path }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

That's it. Every push to main uploads a report to the MemBrowse Portal, and every PR gets a comment showing the memory impact.

MemBrowse updates existing comments instead of creating new ones, so each push to a PR updates the same comment rather than creating noise.

Skipping Builds for Non-Source Commits

Not every commit affects your firmware. Documentation changes, CI config updates, or README edits don't change the ELF output, so there's no point rebuilding and re-analyzing. But MemBrowse still needs to know about these commits to keep the commit chain intact — otherwise there would be gaps in your history.

Use identical: true to upload just the commit metadata without running a build or ELF analysis. MemBrowse records the commit and links it to the previous report's memory data.

A common pattern is to detect whether source files changed and conditionally skip the build:

      - name: Check for source changes
id: changes
uses: dorny/paths-filter@v3
with:
filters: |
firmware:
- 'src/**'
- 'lib/**'
- 'Makefile'
- '*.ld'

- name: Build firmware
if: steps.changes.outputs.firmware == 'true'
run: make all

- name: Analyze memory
id: analyze
continue-on-error: true
uses: membrowse/membrowse-action@v1
with:
elf: build/firmware.elf
ld: linker.ld
target_name: my-target
api_key: ${{ secrets.MEMBROWSE_API_KEY }}
identical: ${{ steps.changes.outputs.firmware != 'true' }}

When identical is true, elf is not required — no build output is needed.

Action Reference

Inputs (membrowse/membrowse-action@v1)

InputRequiredDescription
elfNoPath to ELF file. Not required when identical=true.
ldNoPath to linker script(s), space-separated. If omitted, MemBrowse uses default Code/Data regions based on ELF section flags.
target_nameYesName for this build target
api_keyNoMemBrowse API key. Not required for tokenless uploads in open-source projects.
api_urlNoMemBrowse API base URL (default: https://api.membrowse.com)
linker_varsNoLinker script variable definitions, space-separated (e.g., __flash_size__=4096K __ram_size__=256K)
dont_fail_on_alertsNoDon't exit with failure on budget alerts (default: false)
verboseNoLogging level: WARNING, INFO, or DEBUG (default: WARNING)
pr_author_nameNoPR author name (auto-detected from GitHub event if not provided)
pr_author_emailNoPR author email (auto-detected from GitHub event if not provided)
identicalNoMetadata-only upload, skip ELF analysis (default: false)

Outputs

OutputDescription
report_pathFile path to the generated JSON report file

Inputs (membrowse/membrowse-action/comment-action@v1)

The comment-action supports two modes: file mode (reads local JSON report files) and summary mode (fetches per-target summaries from the MemBrowse API). Use file mode for standard workflows, and summary mode when report artifacts aren't available (e.g., cross-workflow comments).

InputRequiredDescription
json_filesNoSpace-separated list of JSON report file paths or glob pattern (e.g., reports/*.json). Used in file mode.
api_keyNoMemBrowse API key. When provided with commit, enables summary mode — fetches data from the API instead of reading JSON files.
commitNoCommit SHA to fetch summary for. Requires api_key.
pr_numberNoPR number to post comment on. Auto-detected from GitHub event context or commit SHA if not provided.
api_urlNoMemBrowse API base URL (default: https://api.membrowse.com)
comment_templateNoPath to a custom Jinja2 template file for comment formatting

Either json_files or both api_key + commit must be provided.

For more details, see the membrowse-action repository.

Troubleshooting

Analysis step fails

  • Verify the elf and ld paths are correct relative to the repository root
  • Ensure the build step actually produces the ELF file before the analysis step runs
  • Check the step logs — the action prints the resolved file paths

PR comment not appearing

  • Confirm pull-requests: write is set in permissions
  • The comment step only runs on pull_request events, not on pushes to main
  • Check that the analyze step succeeded (outcome == 'success')

API key issues

  • Verify the secret name matches exactly: MEMBROWSE_API_KEY
  • Ensure the key is for the correct project in Project Settings
  • Fork PRs cannot access repository secrets — see Open Source Projects for handling this

Next Steps

  • Multiple targets? If you build for different boards, build types, or feature variants, see Multiple Targets
  • Historical data? Populate your project with past commits using Historical Onboarding
  • Open-source project? Handle fork PRs with the Open Source two-workflow setup