-
Notifications
You must be signed in to change notification settings - Fork 1
feat: add support for automatic channel detection (stable/beta/dev/canary) #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: add support for automatic channel detection (stable/beta/dev/canary) #9
Conversation
- Introduced a detectChannel() method in CheckUpdate.java that: - Checks if the default executable exists and parses the version string to detect channel (e.g., stable, beta, dev). - Falls back to checking common insider build executables (, , etc.) if default fails. - Updated EdgeUpdateService.java (main method) to: - Automatically detect the installed channel before performing update. - Set the detected channel via FetchPackages.setChannel() dynamically. - Updated FetchPackages to support dynamic channel configuration instead of hardcoding . This ensures the update mechanism works across Stable, Beta, Dev, and Canary channels without user input. Related to issue: SaptarshiSarkar12#6
|
@abhisheks-gh There are some syntax errors in the Java classes. Can you please fix those? |
1e7f07e to
104dafb
Compare
|
Hi @SaptarshiSarkar12 , I have fixed those errors - check once and let me know. |
SaptarshiSarkar12
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@abhisheks-gh Thank you for the PR! Great work 👏.
I have reviewed the PR; check the comments below.
One more thing I would like to say is that in
| if (line.contains("microsoft-edge-beta") && line.contains("amd64.deb")) { |
microsoft-edge-beta.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The checkInitDeps() method looks for microsoft-edge-beta by default. Do you have any idea to fix that? We can check and update the channel at the start of the application. We can then use the channel to check for deps and then proceed further.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@abhisheks-gh I think this issue has not been solved yet. Can you please figure out a solution for this problem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the updateEdge() method, the link is hardcoded and doesn't dynamically change with the channel.
This is the line I'm talking about: utils.SystemOps.downloadEdgePackage("https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-beta/" + latestPkg);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@abhisheks-gh This issue also needs fixing. I think we can introduce a static variable (maybe called as channel) in the EdgeUpdateService class, which will be set by the detectInstalledChannel method. We can then use that static variable everywhere required.
Co-authored-by: Saptarshi Sarkar <[email protected]>
- Deleted checkInsiderExecutables() as it is now redundant - Fallback logic for insider channel detection is already handled in detectInstalledChannel() - No other code references this method
Changed path to - "/usr/bin/microsoft-edge-beta"
|
Hi @abhisheks-gh 👋! |
Hi @SaptarshiSarkar12 , no rush as I still need to check and fix a few things on my end and will do so when I get time. Wishing you a speedy recovery. |
|
Hi @abhisheks-gh 👋! |
|
Hi @SaptarshiSarkar12 , Glad to hear that you had a quick recovery. Could you please review the PR now. I believe, we are good to go. Thanks! |
Hi @abhisheks-gh 👋! Thank you for the kind words. |
|
@abhisheks-gh I have left 2 comments in the previous review comments. Please check those out and inform me once completed. Let me know if you have any questions. |
📝 WalkthroughWalkthroughDetects the installed Edge channel, sets FetchPackages.channel accordingly, updates the update flow to accept a channel, builds channel-specific package URLs using a helper to map channel→binary name, adds channel-detection API, and refactors Edge version retrieval to stream-read and parse process output. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant User
participant EdgeUpdateService
participant CheckUpdate
participant FetchPackages
participant Repo as packages.microsoft.com
participant SystemOps
User->>EdgeUpdateService: execute()
EdgeUpdateService->>CheckUpdate: detectInstalledChannel()
CheckUpdate-->>EdgeUpdateService: channel (stable|beta|dev|canary|null)
EdgeUpdateService->>FetchPackages: setChannel(channel)
EdgeUpdateService->>EdgeUpdateService: getEdgeBinaryName(channel)
EdgeUpdateService->>Repo: GET /repos/edge/pool/.../{pkgPath}/{latestPkg}
Repo-->>EdgeUpdateService: .deb package
EdgeUpdateService->>SystemOps: getCurrentEdgeVersion()
SystemOps-->>EdgeUpdateService: current version
EdgeUpdateService->>EdgeUpdateService: install/update (.deb) & cleanup
EdgeUpdateService-->>User: done / status
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used🧠 Learnings (2)📓 Common learnings📚 Learning: 2025-09-06T17:30:57.843ZApplied to files:
🧬 Code graph analysis (1)src/main/java/utils/CheckUpdate.java (1)
🔇 Additional comments (5)
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. 🧪 Early access (Sonnet 4.5): enabledWe are currently testing the Sonnet 4.5 model, which is expected to improve code review quality. However, this model may lead to increased noise levels in the review comments. Please disable the early access features if the noise level causes any inconvenience. Note:
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
♻️ Duplicate comments (2)
src/main/java/utils/CheckUpdate.java (1)
65-90: Channel detection uses a relative binary and misses stable fallback; make it robust and absolute.
- Re-introduces the “relative path” issue previously flagged by code scanning. Prefer absolute paths.
- If the
microsoft-edgeinvocation fails, there’s no stable fallback in the catch branch.- Prefer checking for channel-specific binaries first, then parse output if needed.
- public static String detectInstalledChannel() { - try { - ProcessBuilder pb = new ProcessBuilder("microsoft-edge", "--version"); - Process process = pb.start(); - - try (BufferedReader reader = new BufferedReader( - new InputStreamReader(process.getInputStream()))) { - - String output = reader.readLine(); - if (output != null) { - output = output.toLowerCase(); - if (output.contains("beta")) return "beta"; - if (output.contains("dev")) return "dev"; - if (output.contains("canary")) return "canary"; - return "stable"; // default if none found - } - } - } catch (IOException e) { - // Fallback: check for insider builds - if (SystemOps.isCommandAvailable("microsoft-edge-beta")) return "beta"; - if (SystemOps.isCommandAvailable("microsoft-edge-dev")) return "dev"; - if (SystemOps.isCommandAvailable("microsoft-edge-canary")) return "canary"; - } - // If everything fails - return null; -} + public static String detectInstalledChannel() { + // Prefer explicit binaries first + if (SystemOps.isCommandAvailable("microsoft-edge-canary")) return "canary"; + if (SystemOps.isCommandAvailable("microsoft-edge-dev")) return "dev"; + if (SystemOps.isCommandAvailable("microsoft-edge-beta")) return "beta"; + if (SystemOps.isCommandAvailable("microsoft-edge") || SystemOps.isCommandAvailable("microsoft-edge-stable")) + return "stable"; + + // Fallback: try reading version output from stable path if present + try { + ProcessBuilder pb = new ProcessBuilder("/usr/bin/microsoft-edge", "--version"); + Process process = pb.start(); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + String output = reader.readLine(); + if (output != null) { + String out = output.toLowerCase(); + if (out.contains("canary")) return "canary"; + if (out.contains("dev")) return "dev"; + if (out.contains("beta")) return "beta"; + return "stable"; + } + } + } catch (IOException ignored) { + // no-op + } + // Final default + return "stable"; + }Optional: If you want to avoid duplicating path resolution, expose
SystemOps.getCommandPathas public:// In SystemOps.java - private static String getCommandPath(String command) { + public static String getCommandPath(String command) {src/main/java/main/EdgeUpdateService.java (1)
37-42: Past comment addressed: deps now use channel-specific binary.The dependency list now uses a channel-derived Edge binary instead of the previous hardcoded microsoft-edge-beta. Once the stable mapping fix (see below) is applied, this fully resolves the earlier feedback.
🧹 Nitpick comments (2)
src/main/java/utils/FetchPackages.java (1)
15-22: Harden setChannel: normalize input and avoid misleading log.Trim/case-normalize input; if invalid, say you’re keeping the current channel (not “default: beta”) to avoid confusion.
public static void setChannel(String newChannel) { - if (List.of("stable", "beta", "dev", "canary").contains(newChannel)) { + if (newChannel != null) newChannel = newChannel.trim().toLowerCase(); + if (List.of("stable", "beta", "dev", "canary").contains(newChannel)) { channel = newChannel; } else { - System.out.println("Invalid channel. Using default: beta."); + System.out.println("Invalid channel '" + newChannel + "'. Keeping current: " + channel); } }src/main/java/utils/SystemOps.java (1)
7-7: Remove unused import.
java.nio.Bufferis unused.-import java.nio.Buffer;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (4)
src/main/java/main/EdgeUpdateService.java(3 hunks)src/main/java/utils/CheckUpdate.java(2 hunks)src/main/java/utils/FetchPackages.java(1 hunks)src/main/java/utils/SystemOps.java(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/main/java/main/EdgeUpdateService.java (3)
src/main/java/utils/CheckUpdate.java (1)
CheckUpdate(10-93)src/main/java/utils/FetchPackages.java (1)
FetchPackages(9-44)src/main/java/utils/SystemOps.java (1)
SystemOps(12-195)
src/main/java/utils/CheckUpdate.java (2)
src/main/java/utils/SystemOps.java (1)
SystemOps(12-195)src/main/java/utils/FetchPackages.java (1)
FetchPackages(9-44)
🔇 Additional comments (2)
src/main/java/utils/CheckUpdate.java (1)
3-5: LGTM on imports.Required for process output parsing and exception handling.
src/main/java/main/EdgeUpdateService.java (1)
77-82: No change needed for stable binary name
The CLI binary for stable releases ismicrosoft-edge(the repo/package name ismicrosoft-edge-stable), so the existing default return is correct. If you need to derive the Debian/Ubuntu package or repo path, introduce a separate mapping or helper rather than conflating binary names with package names.Likely an incorrect or invalid review comment.
|
|
||
| public class FetchPackages { | ||
| private static final String channel = "beta"; | ||
| private static String channel = "beta"; // Default if not overridden |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Channel is mutable but URL is not; plus HttpClient is used incorrectly (compilation failure).
- Bug 1:
channelcan change, butpkgLinkisfinaland captured at class-load time. Any latersetChannel()has no effect on the URL. - Bug 2:
HttpClientis not AutoCloseable; using it in try-with-resources won’t compile.
Fix both by computing the URL on demand and removing the try-with-resources; also add basic status/timeout handling.
- private static final String pkgLink = "https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-" + channel + "/";
+ // URL computed on demand from current channel
@@
- private static String getResponse() {
- try (HttpClient client = HttpClient.newHttpClient()) {
- HttpRequest request = HttpRequest.newBuilder()
- .uri(URI.create(pkgLink))
- .GET()
- .build();
- return client.send(request, HttpResponse.BodyHandlers.ofString()).body();
- } catch (Exception e) {
- System.out.println("Error: " + e.getMessage());
- return null;
- }
- }
+ private static String getResponse() {
+ try {
+ HttpClient client = HttpClient.newBuilder()
+ .connectTimeout(java.time.Duration.ofSeconds(10))
+ .build();
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(URI.create(buildPkgLink()))
+ .timeout(java.time.Duration.ofSeconds(10))
+ .GET()
+ .build();
+ HttpResponse<String> resp = client.send(request, HttpResponse.BodyHandlers.ofString());
+ if (resp.statusCode() >= 200 && resp.statusCode() < 300) {
+ return resp.body();
+ }
+ System.out.println("HTTP " + resp.statusCode() + " when fetching packages for channel: " + channel);
+ return null;
+ } catch (Exception e) {
+ System.out.println("Error: " + e.getMessage());
+ return null;
+ }
+ }Add this helper (outside the shown range):
private static String buildPkgLink() {
String dir = "stable".equals(channel) ? "microsoft-edge-stable" : "microsoft-edge-" + channel;
return "https://packages.microsoft.com/repos/edge/pool/main/m/" + dir + "/";
}Also applies to: 11-11, 24-35
🤖 Prompt for AI Agents
In src/main/java/utils/FetchPackages.java around lines 10 (also apply fixes at
11 and 24-35): the class currently defines a mutable static channel but captures
the package URL in a final field at class-load time and uses HttpClient inside a
try-with-resources (which fails to compile because HttpClient is not
AutoCloseable). Change to compute the package URL on demand via a helper method
(e.g., buildPkgLink() that returns the URL based on the current channel) instead
of a final pkgLink constant, remove the try-with-resources around HttpClient and
instantiate a single HttpClient normally (not closed), and add basic HTTP status
checking and a request timeout when sending the request so failures/timeouts are
handled and updated channel values affect the computed URL.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@abhisheks-gh The changes suggested by the bot is correct and must be applied to fix the bug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (3)
src/main/java/main/EdgeUpdateService.java (3)
59-61: Bug: latestPkg may be from the wrong channel (beta) — pass channel through.CheckUpdate.getLatestPkgName() reads a static, eagerly-fetched package list that’s frozen to beta. You must request the list for the same channel you download from.
Apply:
- String latestPkg = CheckUpdate.getLatestPkgName(); + String latestPkg = CheckUpdate.getLatestPkgName(channel); // per-channelNote: Update utils/CheckUpdate.java to accept a channel and to remove the static eager fetch so it respects utils.FetchPackages.setChannel(channel).
29-37: Detect once, then use it for deps and update; avoid early static init and duplication.Current flow detects here and also inside checkInitDeps(), while checkInitDeps() is called earlier. Detect once, set channel, then run deps and update to avoid initializing CheckUpdate (and its beta-frozen packages) twice.
Apply:
utils.FetchPackages.setChannel(detectedChannel); System.out.println("Detected channel: " + detectedChannel); - - updateEdge(detectedChannel); + checkInitDeps(detectedChannel); // move deps check here + updateEdge(detectedChannel);Also remove the early call to checkInitDeps() near Line 14 (outside this hunk) to prevent double init.
41-47: Don’t re-detect here; accept the channel and use it for deps.Make deps check pure and parameterized; drop the extra detect that triggers CheckUpdate’s static init.
Apply:
- private static void checkInitDeps() { - String detectedChannel = CheckUpdate.detectInstalledChannel(); - String edgeBinary = getEdgeBinaryName(detectedChannel); + private static void checkInitDeps(String channel) { + if (channel == null) channel = "stable"; + String edgeBinary = getEdgeBinaryName(channel);Call site: use checkInitDeps(detectedChannel) after detection (see comment on Lines 29–37).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
src/main/java/main/EdgeUpdateService.java(3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/main/java/main/EdgeUpdateService.java (3)
src/main/java/utils/CheckUpdate.java (1)
CheckUpdate(10-93)src/main/java/utils/FetchPackages.java (1)
FetchPackages(9-44)src/main/java/utils/SystemOps.java (1)
SystemOps(12-195)
| public static void updateEdge(String channel) { | ||
| String latestPkg = CheckUpdate.getLatestPkgName(); | ||
| if (latestPkg == null) { | ||
| System.out.println("No Edge update available."); | ||
| } else { | ||
| String pkgPath = getEdgeBinaryName(channel); | ||
|
|
||
| System.out.println("Latest Package: " + latestPkg); | ||
| System.out.println("New Edge update is available."); | ||
| System.out.println("Downloading the latest package..."); | ||
| utils.SystemOps.downloadEdgePackage("https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-beta/" + latestPkg); | ||
|
|
||
| utils.SystemOps.downloadEdgePackage( | ||
| "https://packages.microsoft.com/repos/edge/pool/main/m/" + pkgPath + "/" + latestPkg | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Verify and fix upstream static-initialization pitfalls in utils.
FetchPackages.pkgLink is static final and computed with "beta"; CheckUpdate holds a static List packages. Both must be de-staticized/lazily fetched per channel to make the above changes effective.
Run:
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Check for static eager fetches:"
rg -nP 'private\s+static\s+final\s+String\s+pkgLink' -C2 -- glob:'**/src/main/java/**/*.java'
rg -nP 'private\s+static\s+final\s+List<\s*String\s*>\s*packages' -C2 -- glob:'**/src/main/java/**/*.java'
rg -nP '\bHttpRequest\.newHttpRequestBuilder\(' -C2 -- glob:'**/src/main/java/**/*.java' # invalid builder; should be newBuilder()
rg -nP '\bgetLatestPkgName\s*\(' -C2 -- glob:'**/src/main/java/**/*.java'Length of output: 260
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Directories at root level:"
find . -maxdepth 2 -type dLength of output: 239
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Checking for static eager fetches and builder usage:"
rg -nP 'private\s+static\s+final\s+String\s+pkgLink' -C2 --glob 'src/main/java/**/*.java'
rg -nP 'private\s+static\s+final\s+List<\s*String\s*>\s*packages' -C2 --glob 'src/main/java/**/*.java'
rg -nP 'HttpRequest\.newHttpRequestBuilder' -C2 --glob 'src/main/java/**/*.java'
rg -nP 'getLatestPkgName\s*\(' -C2 --glob 'src/main/java/**/*.java'Length of output: 1375
De-staticize static pkgLink and packages for channel-specific updates
FetchPackages.pkgLink (utils/FetchPackages.java:11) and CheckUpdate.packages (utils/CheckUpdate.java:12) are both static final and use the default "beta" channel at class load, causing updateEdge(channel) to always target beta. Refactor to generate pkgLink and packages lazily per channel parameter.
🤖 Prompt for AI Agents
In src/main/java/main/EdgeUpdateService.java around lines 59-72,
updateEdge(String channel) uses helpers that read static final fields
pre-initialized to the "beta" channel; change the code and the helper classes so
pkgLink and packages are computed per-channel at runtime. Specifically, remove
or stop using static final pkgLink/packages in utils/FetchPackages and
utils/CheckUpdate, add methods that accept a channel parameter (e.g.,
FetchPackages.getPkgLink(channel) and CheckUpdate.getPackages(channel) or
constructors that take channel), update updateEdge to call those channel-aware
methods to build the download URL, and ensure any caching is done per-channel
(not as a single static field) and is thread-safe. Ensure all call sites are
updated accordingly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@abhisheks-gh Take a look at this. We need to initialise the pkgLink variable after the channel is fetched.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!
Hi @SaptarshiSarkar12 , I've resolved the concerns you highlighted. You can check it back now. Also, there are some suggestions from the action bot that you may look at. Thanks |
|
Thank you @abhisheks-gh for the quick fixes. I will review it soon. |
SaptarshiSarkar12
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@abhisheks-gh Awesome work 👏. Left a few comments. Please look into those.
|
|
||
| public class FetchPackages { | ||
| private static final String channel = "beta"; | ||
| private static String channel = "beta"; // Default if not overridden |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@abhisheks-gh The changes suggested by the bot is correct and must be applied to fix the bug.
| public static void updateEdge(String channel) { | ||
| String latestPkg = CheckUpdate.getLatestPkgName(); | ||
| if (latestPkg == null) { | ||
| System.out.println("No Edge update available."); | ||
| } else { | ||
| String pkgPath = getEdgeBinaryName(channel); | ||
|
|
||
| System.out.println("Latest Package: " + latestPkg); | ||
| System.out.println("New Edge update is available."); | ||
| System.out.println("Downloading the latest package..."); | ||
| utils.SystemOps.downloadEdgePackage("https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-beta/" + latestPkg); | ||
|
|
||
| utils.SystemOps.downloadEdgePackage( | ||
| "https://packages.microsoft.com/repos/edge/pool/main/m/" + pkgPath + "/" + latestPkg | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@abhisheks-gh Take a look at this. We need to initialise the pkgLink variable after the channel is fetched.
Removed channel string that was storing result from detectInstalledChannel() Co-authored-by: Saptarshi Sarkar <[email protected]>
Summary
This PR adds support for automatically detecting the installed Microsoft Edge channel (Stable, Beta, Dev, or Canary) and dynamically updating the FetchPackages URL accordingly.
Key Changes
detectChannel()inCheckUpdate.javato determine which Edge channel is installed.EdgeUpdateService.java) now auto-detects the channel and sets it before performing update.FetchPackagesto accept and apply dynamic channels.Why This Is Needed
Previously, EUS only supported the Beta channel. Many users prefer Stable or Dev versions. This change makes EUS more flexible and production-friendly.
Related Issue
Fixes #6
Summary by CodeRabbit
New Features
Bug Fixes
Chores