Skip to content

feat: upgrade-opencode stays on its major; --major/--version switches (fixes #99) - #105

Merged
steffenmaechtel merged 4 commits into
masterfrom
feature/upgrade-opencode-major
Sep 25, 2026
Merged

steffenmaechtel merged 4 commits into
masterfrom
feature/upgrade-opencode-major

Conversation

@steffenmaechtel

Copy link
Copy Markdown
Owner

What

Two topics in one branch: the issue-#99 upgrade semantics for the
opencode binary, and the fix for the e2e-ddev-2x CI crash (plus the
workflow-validation follow-up).

opencode upgrades never cross majors silently (#99)

opk upgrade-opencode resolved "latest" through GitHub
releases/latest — which is always 1.x — so a 2.x install was silently
downgraded (v2.0.11 -> 1.18.32).

  • Default: the latest release of the installed major — 1.x via
    GitHub releases, 2.x via the npm dist-tag latest of
    @opencode/cli-<target> (the channel the official v2 installer
    resolves through; legacy @opencode-ai scope as fallback). A
    resolution off the requested major fails loudly with a
    --major-switch hint instead of crossing.
  • --major 1|2 switches the major explicitly; --version <ver>
    pins an exact release (channel by prefix). Both pass through
    opk upgrade-opencode (and work on opk update).
  • A major flip re-anchors the TUI registration immediately
    (sync_tui_registration: 2.x plugin dir registered, removed on 1.x —
    the 1.x tui.json/danger theme are major-agnostic), even in
    --only-binary runs.
  • detect_target split out of detect_asset (npm package suffix ==
    GitHub target string).

Unit tests: fake-curl resolution matrix (major detection, dist-tag
refusal off-major, npm vs GitHub tarball layouts, current-major default).
e2e: new 2.x-gated section 11d runs a live opk upgrade-opencode and
asserts the binary stays 2.x with the plugin registered. Docs: cli.md,
how-to/update.md, opencode-2x.md §5.

Fixes #99.

e2e: rate-limit-resilient version resolution (CI crash 2026-09-25)

The e2e-ddev-2x job died at cannot resolve a ddev version: the ddev
version came from unauthenticated api.github.com (60 req/h per IP),
which shared GitHub-runner IPs routinely exhaust; the golden-image label
fallback does not exist on a fresh runner, and only the ddev jobs need
the API (the 2x opencode jobs resolve via npm), so everything else
stayed green.

  • lib.sh gains gh_latest_tag <owner/repo>: REST API first —
    authorized via OPK_GH_TOKEN/GITHUB_TOKEN when present (1000+ req/h)
    — then the releases/latest HTML redirect (no API, no rate limit).
    e2e_resolve_cache (opencode 1.x) and run-ddev.sh (ddev) resolve
    through it.
  • The workflows map the ephemeral ${{ github.token }} onto
    OPK_GH_TOKEN at the e2e steps — merged into the existing step
    env blocks (a second env: block made GitHub reject the file; new
    structural guard in test-workflows.sh now fails make test on any
    step with more than one env block).

Validation

  • make test, make lint, workflow-consistency + PyYAML parse — green
  • live: gh_latest_tag resolves ddev 1.25.4 / opencode 1.18.32 (API and
    redirect paths)
  • e2e-ddev with the failing CI config (E2E_OC_VERSION=2.0.16):
    70 passed; make e2e: 269 passed; make e2e-rootless:
    47 passed — all exit 0

…ion switches (issue #99)

opk upgrade-opencode used GitHub releases/latest — always 1.x — so a 2.x
install was silently downgraded (v2.0.11 -> 1.18.32). Version resolution
now never crosses majors:

- default: the latest release of the CURRENT major — 1.x through GitHub
  releases/latest, 2.x through the npm dist-tag latest of
  @opencode/cli-<target> (the channel the official v2 installer resolves
  through; legacy @opencode-ai scope as fallback). A resolution off the
  requested major fails loudly.
- --major 1|2 switches the major explicitly; --version <ver> pins an
  exact release (channel by prefix). Both work through opk
  upgrade-opencode pass-through.
- a major flip re-anchors the TUI registration immediately
  (sync_tui_registration: 2.x plugin dir registered / removed on 1.x)
  even in --only-binary runs; full updates keep it anchored to the stamp.
- detect_target split out of detect_asset (npm package suffix == GitHub
  target string).

Unit tests: fake-curl resolution matrix (majors, off-major dist-tag
refusal, npm vs GitHub tarball layouts, current-major default). e2e: new
2.x-gated section 11d runs a live 'opk upgrade-opencode' and asserts the
binary stays 2.x with the plugin registered. Docs: cli.md,
how-to/update.md, opencode-2x.md §5.
The e2e-ddev-2x CI job died at 'cannot resolve a ddev version'
(2026-09-25): the ddev version was resolved through unauthenticated
api.github.com (60 req/h per IP), and shared GitHub-runner IPs routinely
exhaust that — five retries burned ~52 s, the golden-image label fallback
does not exist on a fresh runner, and only the ddev jobs need the API
(the 2x opencode jobs resolve through npm), so everything else stayed
green.

lib.sh gains gh_latest_tag <owner/repo>: REST API first — authorized with
OPK_GH_TOKEN/GITHUB_TOKEN when exported (1000+ req/h) — then the
releases/latest HTML redirect (no API, no per-IP rate limit) as fallback.
e2e_resolve_cache (opencode 1.x) and run-ddev.sh (ddev) now resolve
through it. The workflows map the ephemeral workflow token onto
OPK_GH_TOKEN at every e2e step — nothing to configure, no secret.

Verified live: gh_latest_tag resolves ddev 1.25.4 and opencode 1.18.32
(both paths); e2e-ddev with the failing CI config (opencode 2.0.16) 70
passed, e2e 269 passed, e2e-rootless 47 passed. New structural checks in
test-e2e-sources.sh pin the token header, the redirect fallback, and the
workflow exports.
…rkflow)

The ddev workflow's run steps already carried env blocks (E2E_DDEV_SITE,
DDEV_VERSION); appending a second env: made GitHub reject the whole file
('env' is already defined, lines 124/186). Merge the token into the
existing blocks. New structural guard in test-workflows.sh fails make
test on any step with more than one env block, and both workflows parse
clean (PyYAML).

@steffenmaechtel steffenmaechtel left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed

@steffenmaechtel
steffenmaechtel merged commit f824a37 into master Sep 25, 2026
6 checks passed
@steffenmaechtel
steffenmaechtel deleted the feature/upgrade-opencode-major branch September 25, 2026 20:48
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.

Upgrade opencode 2.x

1 participant