Skip to content

ci(release): revive packaging pipeline and slim crash symbols - #518

Merged
16bit-ykiko merged 11 commits into
mainfrom
ci/release-pipeline
Jul 18, 2026
Merged

16bit-ykiko merged 11 commits into
mainfrom
ci/release-pipeline

Conversation

@16bit-ykiko

@16bit-ykiko 16bit-ykiko commented Jul 17, 2026 •

Copy link
Copy Markdown
Member

Summary

The release packaging workflow had not run since v0.1.0-alpha.4. This PR makes it verifiable without tagging, trims the shipped artifacts, and makes stripped-binary crash logs offline-symbolizable — verified by three green six-target packaging runs and a new always-on CI round-trip test.

Changes

Workflow

  • publish-clice.yml gains workflow_dispatch, so the full six-target packaging matrix can be exercised from any branch; release uploads stay tag-gated.
  • Per-target compiler caches (ccache/sccache), mirroring native-test.
  • Symbol assets switch to .tar.xz; full DWARF debug info is uploaded as a per-run CI artifact (90-day retention) instead of bloating the release page.

Release binaries

Crash symbolization

  • The crash handler records the main executable's load bias (main executable base), making PIE crash logs rebasable offline. Without it, ASLR-shifted raw addresses are unrecoverable — and embedding debug info in the shipped binary would not help, since in-process symbolization needs llvm-symbolizer on the user machine.
  • Released symbol packages carry GSYM (13 MB) instead of gzip DWARF (252 MB), with full function/line/inline fidelity for symbolization.
  • New scripts/symbolize.py turns a user crash log plus the symbol file into a symbolized stack.

Tests

  • Unit test for the executable-base query; crash-log assertion added to the worker-crash integration test.
  • New integration test replays the release strip/GSYM separation on the built binary, crashes a worker, and asserts symbolize.py recovers source locations from the raw-address log. It runs in every normal CI, so crash-log actionability cannot silently regress.

Validation

  • Three workflow_dispatch runs of the packaging matrix: all six targets green, the last on the final no-LTO configuration.
  • Local release configuration: unit (1016) + integration (289) + smoke (3) suites green; crash → symbolize round-trip verified on the stripped, packaged binary.
  • Artifact sizes: main package 15 MB; symbol package 13 MB (previously 252 MB); full DWARF 237–273 MB compressed as CI artifacts.

Summary by CodeRabbit

  • New Features
    • Crash logs now include the main executable base to enable offline symbolization.
    • Added a CLI tool to rebase and symbolize crash logs.
    • Symbol packaging now uses .tar.xz for non-Windows (Windows uses ZIP) as part of the release flow.
  • Bug Fixes
    • Improved release packaging reliability with per-run compiler cache handling and safer Windows cache shutdown.
    • Release builds now focus on strip/pack plus link optimizations (avoiding LTO/ThinLTO) and improved platform-specific linker folding.
  • Tests
    • Added end-to-end and unit coverage for the symbol separation flow and executable-base behavior.
  • Chores
    • Added/updated release packaging workflows, including a dry-run release check and enhanced debug-information artifact uploads.

Follow-ups in this PR

  • release-check.yml: dry-runs the full packaging matrix automatically on PRs that touch release plumbing (and via workflow_dispatch from any branch), so the pipeline cannot silently rot again.
  • Review findings addressed: GSYM conversion keeps ICF-merged function names (--merged-functions); the crash handler records the executable base unconditionally (a zero macOS slide is valid); symbolize.py tracks the most recent base when a log contains crash sections from several process generations.

@coderabbitai

coderabbitai Bot commented Jul 17, 2026 •

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Release packaging now separates symbols into GSYM or PDB archives, records executable bases in crash logs, and adds a CLI plus integration coverage for offline crash symbolization.

Changes

Release symbol separation

Layer / File(s) Summary
Release packaging and artifacts
CMakeLists.txt, cmake/archive.cmake, cmake/release.cmake, .github/workflows/publish-clice.yml, .github/workflows/release-check.yml
Release builds use linker optimizations instead of automatic LTO, package non-Windows symbols as .tar.xz, publish debug artifacts with compiler-cache management, and provide a dry-run release workflow.
Crash executable-base reporting
src/support/logging.h, src/support/logging.cpp, tests/unit/support/logging_tests.cpp
Logging computes a platform-specific executable base, exposes it through the logging API, writes it to crash logs, and tests the returned value.
External crash symbolizer
scripts/symbolize.py
The CLI parses crash bases and frames, rebases addresses, and invokes llvm-gsymutil or llvm-symbolizer.
Symbol separation integration validation
tests/integration/lifecycle/test_symbolize.py, tests/integration/lifecycle/test_anomaly.py, pixi.toml
Integration coverage recreates stripping and GSYM conversion, triggers a worker crash, and verifies external symbolization and executable-base logging.

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

Sequence Diagram(s)

sequenceDiagram
  participant CrashHandler
  participant CrashLog
  participant SymbolizeCLI
  participant GSYMTool
  CrashHandler->>CrashLog: Write executable base and raw stack frames
  SymbolizeCLI->>CrashLog: Read crash log
  SymbolizeCLI->>GSYMTool: Resolve rebased frame offsets
  GSYMTool-->>SymbolizeCLI: Return symbolized frames
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly reflects the main changes: reviving release packaging and slimming crash symbols.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/release-pipeline

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.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bcbe453fb7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread cmake/release.cmake Outdated
Comment thread scripts/symbolize.py Outdated
Comment thread src/support/logging.cpp Outdated

@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

🤖 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 `@CMakeLists.txt`:
- Around line 71-78: Update the MSVC and clang-cl branch of the linker flag
conditional to append /OPT:ICF directly instead of the -Wl,/OPT:ICF form. Leave
the APPLE and other compiler branches unchanged.

In `@scripts/symbolize.py`:
- Around line 61-76: Update the loop in the symbolization flow to detect each
BASE record as lines are scanned and replace the active base with that record’s
parsed hexadecimal value. Rebase each matching frame using the most recently
encountered base, while preserving the existing missing-base error behavior and
output handling.

In `@src/support/logging.cpp`:
- Around line 143-150: Update the executable-base logging branch in the
crash-log generation flow to always emit the “main executable base” line,
including when executable_base is zero. Remove the truthiness guard while
preserving the existing hexadecimal formatting and newline output.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 71a99694-ab3e-4a17-9cda-2e2782212474

📥 Commits

Reviewing files that changed from the base of the PR and between 3f1dbde and bcbe453.

⛔ Files ignored due to path filters (1)
  • pixi.lock is excluded by !**/*.lock
📒 Files selected for processing (11)
  • .github/workflows/publish-clice.yml
  • CMakeLists.txt
  • cmake/archive.cmake
  • cmake/release.cmake
  • pixi.toml
  • scripts/symbolize.py
  • src/support/logging.cpp
  • src/support/logging.h
  • tests/integration/lifecycle/test_anomaly.py
  • tests/integration/lifecycle/test_symbolize.py
  • tests/unit/support/logging_tests.cpp

Comment thread CMakeLists.txt Outdated
Comment thread scripts/symbolize.py Outdated
Comment thread src/support/logging.cpp Outdated

@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: 1

🤖 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 @.github/workflows/release-check.yml:
- Around line 9-13: Add CMakeLists.txt to the paths list in the release-check
workflow so pull requests modifying release-packaging settings there also
trigger the dry-run validation. Preserve the existing workflow paths 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b492a2cf-82bc-49fb-89e0-bdb544bdf51f

📥 Commits

Reviewing files that changed from the base of the PR and between bcbe453 and d757e06.

📒 Files selected for processing (1)
  • .github/workflows/release-check.yml

Comment thread .github/workflows/release-check.yml

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d757e06fdd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/release-check.yml
Comment thread pixi.toml

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e197ffa4bb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread CMakeLists.txt Outdated
Comment thread scripts/symbolize.py

@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: 1

🤖 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 `@CMakeLists.txt`:
- Around line 73-74: Update the WIN32 linker-flag configuration to distinguish
GNU-style compiler frontends from native MSVC/clang-cl, applying the `-Wl,`
prefix only for GNU drivers and the direct `/OPT:ICF` form for native
MSVC-compatible drivers. Apply the same frontend-specific handling to any nearby
Debug `/OPT:NOICF` configuration if present.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 37509499-a70d-47ad-8a84-cde795772771

📥 Commits

Reviewing files that changed from the base of the PR and between cec35ff and eec72f8.

📒 Files selected for processing (2)
  • CMakeLists.txt
  • cmake/archive.cmake

Comment thread CMakeLists.txt
@16bit-ykiko
16bit-ykiko merged commit 0470445 into main Jul 18, 2026
28 checks passed
@16bit-ykiko
16bit-ykiko deleted the ci/release-pipeline branch July 18, 2026 02:26
16bit-ykiko added a commit that referenced this pull request Jul 18, 2026
Depends on #518 (merged).

## Summary

The VS Code extension no longer downloads the server at runtime. Each of
the six packaging targets now produces a platform-specific vsix with the
clice binary and clang resource directory bundled inside, published via
`vsce publish --target`. This removes the download/extract logic
entirely and makes air-gapped installs work: the binary arrives with the
extension, whether from the Marketplace, a mirror, or a manually
installed vsix.

## Changes

### Extension
- `clice.executable` (and `CLICE_EXECUTABLE`) keep priority; otherwise
the extension resolves the bundled server at `clice/bin/clice[.exe]`
inside the extension directory, restoring the unix executable bit in
case VSIX extraction dropped it. Universal builds without a bundled
server show a clear error pointing at the setting.
- `download.ts` and the `decompress` dependency are removed.

### Release pipeline
- `publish-clice.yml` uploads each platform package as a workflow
artifact.
- `publish-vscode.yml` gains a `bundle` input: PR runs build one
universal vsix (no binary) as a light check; release runs fan out over
six `vsce --target` platforms, staging the matching package into the
extension before packaging. Marketplace publish and release-asset upload
stay tag-gated; the publish step passes an absolute `--packagePath`.
- `release-check.yml` extends the plumbing-PR dry run to cover the six
bundled extension packages.

### Tests
- The vscode e2e suite gains a `bundled-hello_world` variant: the
harness stages the freshly built server into `clice/` in the exact
release layout, clears `CLICE_EXECUTABLE`, and runs the standard
assertions through the bundled-resolution path every release actually
takes. Staging happens before VS Code launches because the extension
activates on startup.
- `editor-test.yml` now also runs the VS Code e2e suite on macOS (no
xvfb needed there); Neovim steps stay Linux-only.

## Validation
- Extension compiles (webpack + tsc) with the bundling changes; a local
`vsce package --target linux-x64` produced a 14.6 MB vsix containing the
binary and clang resources.
- The bundled e2e variant could not run locally (no display server); it
is exercised by the editor-test CI job on both Linux and macOS in this
PR.
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