fix(update): follow the main branch when its channel record is unpublished
A source checkout on the main channel failed every update check with "Could not resolve the main source channel: Channel object not found: releases/channels/main.json" until R2 publishes that record, in the CLI and in Desktop (which asks hermes_cli.source_check). main IS the source branch -- its record can only add a retirement -- so a missing main record now resolves to the main branch and the update continues via git. Other channels, and transient read failures for main, still refuse.
This commit is contained in:
@@ -64,7 +64,8 @@ def _resolve_channel(name: str, repository: str):
|
||||
|
||||
ChannelReader owns HTTPS, authority and digests. The source adapter below
|
||||
admits its retirement constraints before any checkout operation. No legacy
|
||||
GitHub fallback is allowed when a record is unavailable.
|
||||
GitHub fallback is allowed when a record is unavailable; the one exception
|
||||
is an unpublished ``main`` record, which resolves to the main branch.
|
||||
"""
|
||||
from hermes_cli.release_channels import ChannelReader
|
||||
|
||||
@@ -73,11 +74,18 @@ def _resolve_channel(name: str, repository: str):
|
||||
|
||||
def resolve_source_target(channel: str, git_cmd=None, cwd=None, *, repository=None) -> SourceTarget:
|
||||
"""Resolve every subscription, including default labels, through R2."""
|
||||
from hermes_cli.release_channels import validate_name
|
||||
from hermes_cli.release_channels import ChannelNotFound, validate_name
|
||||
|
||||
validate_name(channel)
|
||||
repository = repository or source_repository(git_cmd, cwd)
|
||||
resolved = _resolve_channel(channel, repository)
|
||||
try:
|
||||
resolved = _resolve_channel(channel, repository)
|
||||
except ChannelNotFound:
|
||||
if channel != "main":
|
||||
raise
|
||||
# main IS the source branch; its record can only add a retirement.
|
||||
# Until one is published, a checkout keeps following the branch via git.
|
||||
return SourceTarget(channel, channel, repository, branch="main")
|
||||
terminal = resolved.terminal
|
||||
if terminal["repository"].lower() != repository.lower():
|
||||
raise ValueError("Channel repository does not match this source installation")
|
||||
|
||||
@@ -153,6 +153,25 @@ def test_missing_channel_cannot_fall_back_to_main(source, monkeypatch, channel):
|
||||
assert git(source.root, "rev-parse", "HEAD") == before
|
||||
|
||||
|
||||
def test_unpublished_main_record_keeps_following_the_git_branch(source, monkeypatch):
|
||||
"""main IS the source branch: until R2 publishes its record, a checkout
|
||||
still updates via git instead of failing on a missing channel object."""
|
||||
from hermes_cli import source_check
|
||||
from hermes_cli.release_channels import ChannelNotFound
|
||||
|
||||
set_install_channel("main", source.root)
|
||||
def unpublished(name, repository):
|
||||
raise ChannelNotFound(f"Channel object not found: releases/channels/{name}.json")
|
||||
monkeypatch.setattr(source_releases, "_resolve_channel", unpublished)
|
||||
target = source_releases.resolve_source_target("main", ["git"], source.root)
|
||||
assert target.branch == "main" and target.commit is None
|
||||
status = source_check.check_for_updates(install_root=source.root, home=source.home, force=True)
|
||||
assert "error" not in status, status
|
||||
assert status["targetSha"] == source.commits[2]
|
||||
with pytest.raises(ChannelNotFound):
|
||||
source_releases.resolve_source_target("stable", ["git"], source.root)
|
||||
|
||||
|
||||
def test_passive_check_reports_retirement_without_adopting_it(source, monkeypatch):
|
||||
from hermes_cli import source_check, banner
|
||||
|
||||
|
||||
Reference in New Issue
Block a user