Atavism/linux arm - YAML test#1
Conversation
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
CodeAnt AI is reviewing your PR. Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly expands the Linux build capabilities by enabling multi-architecture support for both Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Ignored Files
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
Sequence DiagramThis PR adds architecture aware Linux release handling by routing a selected linux arch through metadata, build matrix, packaging, and publishing. It ensures amd64 and arm64 artifacts are built, named, and published consistently. sequenceDiagram
participant Maintainer
participant ReleaseWorkflow
participant LinuxBuildJob
participant Makefile
participant ArtifactStore
participant PublishScript
participant Formatter
Maintainer->>ReleaseWorkflow: Trigger release with platform and linux arch
ReleaseWorkflow->>LinuxBuildJob: Start linux matrix for selected arch values
LinuxBuildJob->>Makefile: Build app and service for target arch
Makefile-->>LinuxBuildJob: Produce arch specific deb and rpm packages
LinuxBuildJob->>ArtifactStore: Upload linux artifacts with arch suffix
ReleaseWorkflow->>PublishScript: Publish linux artifacts using linux arch filter
PublishScript->>ArtifactStore: Copy files to version and latest release paths
ReleaseWorkflow->>Formatter: Generate release notes and slack text per linux arch
Generated by CodeAnt AI |
There was a problem hiding this comment.
Code Review
This pull request adds support for building and publishing Linux ARM64 packages. The changes are well-structured, modifying the Makefile for multi-architecture builds and updating CI scripts for release notes and artifact publishing. I have one suggestion for the Makefile to improve maintainability by reducing code duplication in a build recipe. The test harness modifications are also a good improvement for test stability.
| VERSION=$(APP_VERSION) GOARCH=$(LINUX_TARGET_ARCH) LINUX_BUNDLE_SRC="$$BUNDLE_DIR/" SYSTEMD_UNIT_SRC=$(LINUX_SYSTEMD_UNIT_DST) \ | ||
| LANTERND_SRC=$(LINUX_SERVICE_DST)/$(LINUX_SERVICE_NAME) LANTERND_DST=/usr/sbin/$(LINUX_SERVICE_NAME) \ | ||
| nfpm package -f $(LINUX_PKG_ROOT)/nfpm.yaml -p deb -t $(LINUX_INSTALLER_DEB) | ||
| VERSION=$(APP_VERSION) SYSTEMD_UNIT_SRC=$(LINUX_SYSTEMD_UNIT_DST) \ | ||
| nfpm package -f $(LINUX_PKG_ROOT)/nfpm.yaml -p deb -t $(LINUX_INSTALLER_DEB); \ | ||
| VERSION=$(APP_VERSION) GOARCH=$(LINUX_TARGET_ARCH) LINUX_BUNDLE_SRC="$$BUNDLE_DIR/" SYSTEMD_UNIT_SRC=$(LINUX_SYSTEMD_UNIT_DST) \ | ||
| LANTERND_SRC=$(LINUX_SERVICE_DST)/$(LINUX_SERVICE_NAME) LANTERND_DST=/usr/sbin/$(LINUX_SERVICE_NAME) \ | ||
| nfpm package -f $(LINUX_PKG_ROOT)/nfpm.yaml -p rpm -t $(LINUX_INSTALLER_RPM) | ||
| VERSION=$(APP_VERSION) SYSTEMD_UNIT_SRC=$(LINUX_SYSTEMD_UNIT_DST) \ | ||
| nfpm package -f $(LINUX_PKG_ROOT)/nfpm.yaml -p rpm -t $(LINUX_INSTALLER_RPM); \ | ||
| VERSION=$(APP_VERSION) GOARCH=$(LINUX_TARGET_ARCH) LINUX_BUNDLE_SRC="$$BUNDLE_DIR/" SYSTEMD_UNIT_SRC=$(LINUX_SYSTEMD_UNIT_DST) \ | ||
| LANTERND_SRC=$(LINUX_SERVICE_DST)/$(LINUX_SERVICE_NAME) LANTERND_DST=/usr/bin/$(LINUX_SERVICE_NAME) \ | ||
| nfpm package -f $(LINUX_PKG_ROOT)/nfpm.yaml -p archlinux -t $(LINUX_INSTALLER_ARCH) | ||
| nfpm package -f $(LINUX_PKG_ROOT)/nfpm.yaml -p archlinux -t $(LINUX_INSTALLER_ARCH) |
There was a problem hiding this comment.
The three nfpm commands are very similar and repeat a long list of environment variables. This repetition can make the recipe harder to read and maintain. You can define a shell variable to hold the common environment variables to reduce duplication and improve clarity.
NFPM_ENV="VERSION=$(APP_VERSION) GOARCH=$(LINUX_TARGET_ARCH) LINUX_BUNDLE_SRC='$$BUNDLE_DIR/' SYSTEMD_UNIT_SRC=$(LINUX_SYSTEMD_UNIT_DST) LANTERND_SRC=$(LINUX_SERVICE_DST)/$(LINUX_SERVICE_NAME)"; \
$$NFPM_ENV LANTERND_DST=/usr/sbin/$(LINUX_SERVICE_NAME) \
nfpm package -f $(LINUX_PKG_ROOT)/nfpm.yaml -p deb -t $(LINUX_INSTALLER_DEB); \
$$NFPM_ENV LANTERND_DST=/usr/sbin/$(LINUX_SERVICE_NAME) \
nfpm package -f $(LINUX_PKG_ROOT)/nfpm.yaml -p rpm -t $(LINUX_INSTALLER_RPM); \
$$NFPM_ENV LANTERND_DST=/usr/bin/$(LINUX_SERVICE_NAME) \
nfpm package -f $(LINUX_PKG_ROOT)/nfpm.yaml -p archlinux -t $(LINUX_INSTALLER_ARCH)
Nitpicks 🔍
|
📝 WalkthroughWalkthroughThis PR introduces multi-architecture Linux build support (amd64 and arm64) across CI/CD workflows, packaging configuration, and build infrastructure. It parameterizes the build pipeline with selectable target architectures, updates artifact naming and upload logic, and refactors VPN testing to improve reliability. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
📝 Coding Plan
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. Comment |
|
|
||
| $(LINUX_LIB_ARM64): $(GO_SOURCES) | ||
| CC=aarch64-linux-gnu-gcc GOARCH=arm64 LIB_NAME=$@ make desktop-lib | ||
| CC=$(LINUX_CC_ARM64) GOOS=linux GOARCH=arm64 LIB_NAME=$@ $(MAKE) desktop-lib |
There was a problem hiding this comment.
Suggestion: The arm64 library build writes output to bin/linux-arm64/... but never creates that directory first. On clean builds this will fail with a "no such file or directory" error when go build -o tries to write the shared library. [resource leak]
Severity Level: Critical 🚨
- ❌ Linux arm64 release build can fail immediately.
- ❌ CI pipeline blocks Linux artifact production.| CC=$(LINUX_CC_ARM64) GOOS=linux GOARCH=arm64 LIB_NAME=$@ $(MAKE) desktop-lib | |
| $(call MKDIR_P,$(dir $@)) |
Steps of Reproduction ✅
1. Trigger Linux CI build at `.github/workflows/build-linux.yml:155`, which runs `make
linux-release-ci` with `LINUX_TARGET_ARCH=${{ matrix.arch }}` (`:160`), and matrix
includes `arm64` (`:27`).
2. In `Makefile`, `linux-release-ci` (`:318`) depends on `linux` (`:279`), which resolves
to `linux-arm64` and executes target rule `$(LINUX_LIB_ARM64):` at `:269-270`.
3. That rule directly calls `desktop-lib` at `Makefile:270` without creating `$(dir $@)`.
`desktop-lib` runs `go build ... -o $(LIB_NAME)` at `Makefile:177`.
4. On a clean checkout (`actions/checkout` at workflow `:35`), `bin/linux-arm64/` does not
exist, so writing `-o bin/linux-arm64/liblantern.so` fails with missing-directory error.Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** Makefile
**Line:** 270:270
**Comment:**
*Resource Leak: The arm64 library build writes output to `bin/linux-arm64/...` but never creates that directory first. On clean builds this will fail with a "no such file or directory" error when `go build -o` tries to write the shared library.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.|
|
||
| $(LINUX_LIB_AMD64): $(GO_SOURCES) | ||
| CC=x86_64-linux-gnu-gcc GOARCH=amd64 LIB_NAME=$@ make desktop-lib | ||
| CC=$(LINUX_CC_AMD64) GOOS=linux GOARCH=amd64 LIB_NAME=$@ $(MAKE) desktop-lib |
There was a problem hiding this comment.
Suggestion: The amd64 library build has the same missing-directory issue: it writes to bin/linux-amd64/... without ensuring the directory exists first. This breaks clean CI/local runs where that path has not been created yet. [possible bug]
Severity Level: Critical 🚨
- ❌ Linux amd64 release build can fail immediately.
- ❌ Primary CI release workflow becomes unstable.| CC=$(LINUX_CC_AMD64) GOOS=linux GOARCH=amd64 LIB_NAME=$@ $(MAKE) desktop-lib | |
| $(call MKDIR_P,$(dir $@)) |
Steps of Reproduction ✅
1. Trigger Linux CI build at `.github/workflows/build-linux.yml:155` with
`matrix.arch=amd64` (`:27`, passed to `LINUX_TARGET_ARCH` at `:160`).
2. `linux-release-ci` (`Makefile:318`) depends on `linux` (`:279`), which resolves to
`linux-amd64` and runs rule `$(LINUX_LIB_AMD64):` at `:275-276`.
3. Rule line `Makefile:276` invokes `desktop-lib` directly; `desktop-lib` writes output
via `go build ... -o $(LIB_NAME)` (`Makefile:177`) and does not create parent directories.
4. In clean CI workspaces, `bin/linux-amd64/` is absent, so writing
`bin/linux-amd64/liblantern.so` can fail with "no such file or directory".Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** Makefile
**Line:** 276:276
**Comment:**
*Possible Bug: The amd64 library build has the same missing-directory issue: it writes to `bin/linux-amd64/...` without ensuring the directory exists first. This breaks clean CI/local runs where that path has not been created yet.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.| nfpm package -f $(LINUX_PKG_ROOT)/nfpm.yaml -p deb -t $(LINUX_INSTALLER_DEB); \ | ||
| VERSION=$(APP_VERSION) GOARCH=$(LINUX_TARGET_ARCH) LINUX_BUNDLE_SRC="$$BUNDLE_DIR/" SYSTEMD_UNIT_SRC=$(LINUX_SYSTEMD_UNIT_DST) \ | ||
| LANTERND_SRC=$(LINUX_SERVICE_DST)/$(LINUX_SERVICE_NAME) LANTERND_DST=/usr/sbin/$(LINUX_SERVICE_NAME) \ | ||
| nfpm package -f $(LINUX_PKG_ROOT)/nfpm.yaml -p rpm -t $(LINUX_INSTALLER_RPM) | ||
| VERSION=$(APP_VERSION) SYSTEMD_UNIT_SRC=$(LINUX_SYSTEMD_UNIT_DST) \ | ||
| nfpm package -f $(LINUX_PKG_ROOT)/nfpm.yaml -p rpm -t $(LINUX_INSTALLER_RPM); \ |
There was a problem hiding this comment.
Suggestion: The three packaging commands are chained with ;, so failure in the deb/rpm packaging steps can be silently ignored if the final archlinux command succeeds. This can produce partially broken release artifacts while the target still exits successfully. [logic error]
Severity Level: Major ⚠️
- ❌ RPM artifact can be missing while build reports success.
- ⚠️ Partial packaging failures become harder to detect.| nfpm package -f $(LINUX_PKG_ROOT)/nfpm.yaml -p deb -t $(LINUX_INSTALLER_DEB); \ | |
| VERSION=$(APP_VERSION) GOARCH=$(LINUX_TARGET_ARCH) LINUX_BUNDLE_SRC="$$BUNDLE_DIR/" SYSTEMD_UNIT_SRC=$(LINUX_SYSTEMD_UNIT_DST) \ | |
| LANTERND_SRC=$(LINUX_SERVICE_DST)/$(LINUX_SERVICE_NAME) LANTERND_DST=/usr/sbin/$(LINUX_SERVICE_NAME) \ | |
| nfpm package -f $(LINUX_PKG_ROOT)/nfpm.yaml -p rpm -t $(LINUX_INSTALLER_RPM) | |
| VERSION=$(APP_VERSION) SYSTEMD_UNIT_SRC=$(LINUX_SYSTEMD_UNIT_DST) \ | |
| nfpm package -f $(LINUX_PKG_ROOT)/nfpm.yaml -p rpm -t $(LINUX_INSTALLER_RPM); \ | |
| nfpm package -f $(LINUX_PKG_ROOT)/nfpm.yaml -p deb -t $(LINUX_INSTALLER_DEB) && \ | |
| VERSION=$(APP_VERSION) GOARCH=$(LINUX_TARGET_ARCH) LINUX_BUNDLE_SRC="$$BUNDLE_DIR/" SYSTEMD_UNIT_SRC=$(LINUX_SYSTEMD_UNIT_DST) \ | |
| LANTERND_SRC=$(LINUX_SERVICE_DST)/$(LINUX_SERVICE_NAME) LANTERND_DST=/usr/sbin/$(LINUX_SERVICE_NAME) \ | |
| nfpm package -f $(LINUX_PKG_ROOT)/nfpm.yaml -p rpm -t $(LINUX_INSTALLER_RPM) && \ |
Steps of Reproduction ✅
1. CI executes `make linux-release-ci` at `.github/workflows/build-linux.yml:155`, running
packaging recipe at `Makefile:335-343`.
2. The recipe chains three `nfpm package` commands with `;` (`Makefile:337`, `:340`,
`:343`) in one shell line.
3. `Makefile` does not set global shell fail-fast (`.ONESHELL`/`SHELLFLAGS -e` not
defined; only unrelated local `@set -e` appears in iOS block at `Makefile:555`), so the
shell returns the status of the last command.
4. If `deb` or `rpm` packaging fails but `archlinux` succeeds, this line exits success; CI
can proceed and artifact upload for rpm (`.github/workflows/build-linux.yml:256-257`) may
silently publish incomplete outputs.Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** Makefile
**Line:** 337:340
**Comment:**
*Logic Error: The three packaging commands are chained with `;`, so failure in the deb/rpm packaging steps can be silently ignored if the final archlinux command succeeds. This can produce partially broken release artifacts while the target still exits successfully.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.| if (currentState != VPNStatus.connected && | ||
| currentState != VPNStatus.connecting) { | ||
| return; | ||
| } | ||
|
|
||
| await WidgetWaitUtils.waitForFinder( | ||
| tester, | ||
| vpnToggle, | ||
| timeout: const Duration(seconds: 15), | ||
| reason: 'VPN toggle not available for disconnect', | ||
| ); | ||
| await tester.tap(vpnToggle); | ||
| await tester.pump(const Duration(milliseconds: 200)); |
There was a problem hiding this comment.
Suggestion: The disconnect helper decides to tap based on an old state snapshot, then waits for the toggle to reappear; if the state changes from connecting to disconnected during that wait, it will tap anyway and accidentally start a new connection. Re-check the state after waiting and only tap when the current stable state is actually connected. [logic error]
Severity Level: Major ⚠️
- ⚠️ VPN smoke cleanup can trigger unintended reconnect.
- ⚠️ Linux/Windows integration tests become flaky.
- ❌ Failure reason can be masked by cleanup timeout.| if (currentState != VPNStatus.connected && | |
| currentState != VPNStatus.connecting) { | |
| return; | |
| } | |
| await WidgetWaitUtils.waitForFinder( | |
| tester, | |
| vpnToggle, | |
| timeout: const Duration(seconds: 15), | |
| reason: 'VPN toggle not available for disconnect', | |
| ); | |
| await tester.tap(vpnToggle); | |
| await tester.pump(const Duration(milliseconds: 200)); | |
| if (currentState == VPNStatus.disconnected || | |
| currentState == VPNStatus.missingPermission || | |
| currentState == VPNStatus.error) { | |
| return; | |
| } | |
| await WidgetWaitUtils.waitForFinder( | |
| tester, | |
| vpnToggle, | |
| timeout: const Duration(seconds: 15), | |
| reason: 'VPN toggle not available for disconnect', | |
| ); | |
| final stableState = await vpnStateFinders.tryWaitFor( | |
| tester, | |
| expected: const [VPNStatus.connected, VPNStatus.disconnected], | |
| timeout: const Duration(seconds: 15), | |
| ); | |
| if (stableState == VPNStatus.connected) { | |
| await tester.tap(vpnToggle); | |
| await tester.pump(const Duration(milliseconds: 200)); | |
| } |
Steps of Reproduction ✅
1. Run either integration entrypoint
`integration_test/vpn/linux_connect_smoke_test.dart:13-15` or
`integration_test/vpn/windows_connect_smoke_test.dart:13-15`, which both call
`runConnectSmokeHarness(...)`.
2. In `integration_test/vpn/connect_smoke_harness.dart:333-359`, the harness always
executes `_disconnectVpn(...)` in the `finally` block after the connect attempt.
3. Trigger a realistic unstable-connect run where the connect phase (`waitFor` at
`connect_smoke_harness.dart:338-343`) is still transitioning or fails to stabilize;
`_disconnectVpn` then snapshots state once at `:191-194` and proceeds.
4. If UI state flips from `connecting` to `disconnected` while waiting for toggle
visibility (`:197-202`), code still taps at `:203`, toggling from disconnected back toward
connect.
5. Observe cleanup becomes non-deterministic: `_disconnectVpn` may start a new connection
and then wait for disconnected at `:206-211`, causing extra timeout/failure noise in smoke
test results.Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** integration_test/vpn/connect_smoke_harness.dart
**Line:** 192:204
**Comment:**
*Logic Error: The disconnect helper decides to tap based on an old state snapshot, then waits for the toggle to reappear; if the state changes from connecting to disconnected during that wait, it will tap anyway and accidentally start a new connection. Re-check the state after waiting and only tap when the current stable state is actually connected.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.| upload_artifact "$platform" "$extension" "${arch:-}" | ||
| result=$? |
There was a problem hiding this comment.
Suggestion: With set -e, calling the upload function directly will terminate the script immediately on return codes 1 (not found) or 2 (upload failure), so the summary/counting logic never runs. Wrap the call in an if so non-zero statuses can be captured safely instead of triggering errexit. [logic error]
Severity Level: Critical 🚨
- ❌ upload-s3 job fails on first missing artifact.
- ❌ Release flow aborts before aggregated failure accounting.
- ⚠️ Skip/failure summary in lines 159-160 never prints.| upload_artifact "$platform" "$extension" "${arch:-}" | |
| result=$? | |
| if upload_artifact "$platform" "$extension" "${arch:-}"; then | |
| result=0 | |
| else | |
| result=$? | |
| fi |
Steps of Reproduction ✅
1. Trigger the release pipeline job `upload-s3` in
`.github/workflows/release.yml:362-410`; step `Upload to S3` runs
`./scripts/ci/publish-to-s3.sh` at lines 406-410.
2. In `scripts/ci/publish-to-s3.sh`, the script is in errexit mode (`set -euo pipefail` at
line 3) and calls `upload_artifact` directly inside the artifact loop at line 149.
3. If an artifact file is absent, `upload_artifact()` returns `1` at lines 115-117 (`⊘
Skipping ... not found`), or returns `2` on upload failure via `upload_file()` lines
66-75.
4. Because line 149 is a plain command (not guarded by `if`), Bash exits immediately under
`-e` before `result=$?` (line 150), so counting logic (`case` lines 152-156) and summary
output (lines 159-160) never execute.Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** scripts/ci/publish-to-s3.sh
**Line:** 149:150
**Comment:**
*Logic Error: With `set -e`, calling the upload function directly will terminate the script immediately on return codes `1` (not found) or `2` (upload failure), so the summary/counting logic never runs. Wrap the call in an `if` so non-zero statuses can be captured safely instead of triggering errexit.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.|
CodeAnt AI finished reviewing your PR. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@Makefile`:
- Around line 269-270: The recipe for the LINUX_LIB_ARM64 target currently
invokes the desktop-lib make target without ensuring the output directory
exists; update the LINUX_LIB_ARM64 recipe to create the parent directory for $@
before calling desktop-lib (use the same pattern as the Windows/Darwin targets,
e.g. call the MKDIR_P macro on $(dir $@)) so the nested path (e.g.
bin/linux-arm64/) is created prior to running CC=$(LINUX_CC_ARM64) GOOS=linux
GOARCH=arm64 LIB_NAME=$@ $(MAKE) desktop-lib.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: c854437f-e7f5-483c-8681-1e5b5d39e9cc
📒 Files selected for processing (8)
.github/workflows/build-linux.yml.github/workflows/release.ymlMakefileintegration_test/vpn/connect_smoke_harness.dartlinux/packaging/nfpm.yamlscripts/ci/format.shscripts/ci/publish-to-s3.shscripts/ci/verify_linux_package.sh
| $(LINUX_LIB_ARM64): $(GO_SOURCES) | ||
| CC=aarch64-linux-gnu-gcc GOARCH=arm64 LIB_NAME=$@ make desktop-lib | ||
| CC=$(LINUX_CC_ARM64) GOOS=linux GOARCH=arm64 LIB_NAME=$@ $(MAKE) desktop-lib |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
echo "Linux lib target recipes:"
nl -ba Makefile | sed -n '266,281p'
echo
echo "desktop-lib recipe:"
nl -ba Makefile | sed -n '175,181p'
echo
echo "clean recipe:"
nl -ba Makefile | sed -n '618,624p'Repository: coderabbit-test/lantern
Length of output: 152
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
echo "=== Linux lib target recipes (lines 266-281) ==="
sed -n '266,281p' Makefile | cat -n
echo
echo "=== desktop-lib recipe (lines 175-181) ==="
sed -n '175,181p' Makefile | cat -n
echo
echo "=== clean recipe (lines 618-624) ==="
sed -n '618,624p' Makefile | cat -n
echo
echo "=== Checking for MKDIR_P definition ==="
grep -n "MKDIR_P" Makefile | head -20Repository: coderabbit-test/lantern
Length of output: 2123
🏁 Script executed:
#!/bin/bash
echo "=== Searching for LINUX_LIB_ARM64 and LINUX_LIB_AMD64 definitions ==="
grep -n "LINUX_LIB_ARM64\|LINUX_LIB_AMD64" Makefile | grep -v "^\s*#" | head -30
echo
echo "=== Searching for BIN_DIR definition ==="
grep -n "^BIN_DIR" Makefile
echo
echo "=== Searching for LINUX_LIB definition ==="
grep -n "^LINUX_LIB" Makefile | head -10Repository: coderabbit-test/lantern
Length of output: 750
Create the per-arch lib output directories before calling desktop-lib.
These targets write to nested paths like bin/linux-amd64/liblantern.so and bin/linux-arm64/liblantern.so, but neither recipe creates the parent directories. After a clean checkout or after make clean removes bin/*, the nested output paths will be missing before the build even starts, causing the go build step to fail. This pattern is already correctly implemented in other platform targets (Windows and Darwin lib builds use $(call MKDIR_P,$(dir $@))), but is missing here.
🛠️ Proposed fix
$(LINUX_LIB_ARM64): $(GO_SOURCES)
+ $(call MKDIR_P,$(dir $@))
CC=$(LINUX_CC_ARM64) GOOS=linux GOARCH=arm64 LIB_NAME=$@ $(MAKE) desktop-lib
$(LINUX_LIB_AMD64): $(GO_SOURCES)
+ $(call MKDIR_P,$(dir $@))
CC=$(LINUX_CC_AMD64) GOOS=linux GOARCH=amd64 LIB_NAME=$@ $(MAKE) desktop-lib🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@Makefile` around lines 269 - 270, The recipe for the LINUX_LIB_ARM64 target
currently invokes the desktop-lib make target without ensuring the output
directory exists; update the LINUX_LIB_ARM64 recipe to create the parent
directory for $@ before calling desktop-lib (use the same pattern as the
Windows/Darwin targets, e.g. call the MKDIR_P macro on $(dir $@)) so the nested
path (e.g. bin/linux-arm64/) is created prior to running CC=$(LINUX_CC_ARM64)
GOOS=linux GOARCH=arm64 LIB_NAME=$@ $(MAKE) desktop-lib.
CodeAnt-AI Description
Support Linux ARM64 builds, packaging, and more reliable Linux UI smoke tests
What Changed
Impact
✅ Linux ARM64 builds published to releases✅ Fewer Linux CI build and publish failures for mixed-arch runs✅ Fewer flaky Linux UI smoke test failures💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.
Summary by CodeRabbit
New Features
Tests