Setup
Add MemBrowse to your existing GitHub Actions workflow. If you already build your firmware in CI, this takes just a few minutes.
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
- Go to your GitHub repository
- Navigate to Settings > Secrets and variables > Actions
- Click New repository secret
- Name:
MEMBROWSE_API_KEY - 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)
| Input | Required | Description |
|---|---|---|
elf | No | Path to ELF file. Not required when identical=true. |
ld | No | Path to linker script(s), space-separated. If omitted, MemBrowse uses default Code/Data regions based on ELF section flags. |
target_name | Yes | Name for this build target |
api_key | No | MemBrowse API key. Not required for tokenless uploads in open-source projects. |
api_url | No | MemBrowse API base URL (default: https://api.membrowse.com) |
linker_vars | No | Linker script variable definitions, space-separated (e.g., __flash_size__=4096K __ram_size__=256K) |
dont_fail_on_alerts | No | Don't exit with failure on budget alerts (default: false) |
verbose | No | Logging level: WARNING, INFO, or DEBUG (default: WARNING) |
pr_author_name | No | PR author name (auto-detected from GitHub event if not provided) |
pr_author_email | No | PR author email (auto-detected from GitHub event if not provided) |
identical | No | Metadata-only upload, skip ELF analysis (default: false) |
Outputs
| Output | Description |
|---|---|
report_path | File 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).
| Input | Required | Description |
|---|---|---|
json_files | No | Space-separated list of JSON report file paths or glob pattern (e.g., reports/*.json). Used in file mode. |
api_key | No | MemBrowse API key. When provided with commit, enables summary mode — fetches data from the API instead of reading JSON files. |
commit | No | Commit SHA to fetch summary for. Requires api_key. |
pr_number | No | PR number to post comment on. Auto-detected from GitHub event context or commit SHA if not provided. |
api_url | No | MemBrowse API base URL (default: https://api.membrowse.com) |
comment_template | No | Path 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
elfandldpaths 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: writeis set inpermissions - The comment step only runs on
pull_requestevents, 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