fix(install): resolve release asset via Gitea API (download was always 404)
CI / cargo fmt --check (push) Successful in 29s
CI / cargo clippy (push) Successful in 40s
CI / cargo test (push) Successful in 46s
CI / editor keymaps (push) Successful in 1m40s

:NuwikiInstall always fell back to building from source because the
download URL used the GitHub-only shape
`/releases/latest/download/<asset>`, which this Gitea instance serves as
404. The release assets exist and are correctly named; only the URL was
wrong.

Resolve the asset's real download URL through the Gitea API instead: GET
`/api/v1/repos/.../releases/latest`, find the asset matching
`nuwiki-ls-<target>.tar.gz`, and download its `browser_download_url`
(`/releases/download/<tag>/<asset>`, which returns 200). Fixed in both
install paths — lua/nuwiki/install.lua (vim.json.decode) and
scripts/download_bin.vim (json_decode). Verified end to end: resolve →
download → extract → executable binary.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-05 01:41:21 +00:00
parent 34a0607e7a
commit 3c1ed48a2f
2 changed files with 54 additions and 6 deletions
+26 -4
View File
@@ -66,6 +66,28 @@ local function build_from_source(dest)
return vim.fn.executable(dest) == 1 return vim.fn.executable(dest) == 1
end end
-- Gitea API base for this repo. Gitea has no GitHub-style
-- `/releases/latest/download/<asset>` shortcut, so resolve the asset's real
-- download URL (`browser_download_url`) through the API instead.
local REPO_API = 'https://code.gfran.co/api/v1/repos/gffranco/nuwiki'
local function latest_asset_url(asset_name)
local body = vim.fn.system({ 'curl', '-fsSL', REPO_API .. '/releases/latest' })
if vim.v.shell_error ~= 0 then
return nil
end
local ok, release = pcall(vim.json.decode, body)
if not ok or type(release) ~= 'table' or type(release.assets) ~= 'table' then
return nil
end
for _, a in ipairs(release.assets) do
if a.name == asset_name then
return a.browser_download_url
end
end
return nil
end
local function download_release(dest) local function download_release(dest)
local target = target_triple() local target = target_triple()
if not target then if not target then
@@ -74,10 +96,10 @@ local function download_release(dest)
if vim.fn.executable('curl') ~= 1 or vim.fn.executable('tar') ~= 1 then if vim.fn.executable('curl') ~= 1 or vim.fn.executable('tar') ~= 1 then
return false return false
end end
local url = string.format( local url = latest_asset_url('nuwiki-ls-' .. target .. '.tar.gz')
'https://code.gfran.co/gffranco/nuwiki/releases/latest/download/nuwiki-ls-%s.tar.gz', if not url then
target return false
) end
local archive = vim.fn.tempname() .. '.tar.gz' local archive = vim.fn.tempname() .. '.tar.gz'
vim.fn.system({ 'curl', '-fsSL', '-o', archive, url }) vim.fn.system({ 'curl', '-fsSL', '-o', archive, url })
if vim.v.shell_error ~= 0 then if vim.v.shell_error ~= 0 then
+28 -2
View File
@@ -48,6 +48,30 @@ function! s:build_from_source() abort
return executable(s:bin) return executable(s:bin)
endfunction endfunction
" Gitea has no GitHub-style /releases/latest/download/<asset> shortcut, so
" resolve the asset's real download URL (browser_download_url) via the API.
function! s:latest_asset_url(asset) abort
let l:api = 'https://code.gfran.co/api/v1/repos/gffranco/nuwiki/releases/latest'
let l:body = system('curl -fsSL ' . shellescape(l:api))
if v:shell_error != 0
return ''
endif
try
let l:release = json_decode(l:body)
catch
return ''
endtry
if type(l:release) != type({}) || !has_key(l:release, 'assets')
return ''
endif
for l:item in l:release.assets
if get(l:item, 'name', '') ==# a:asset
return get(l:item, 'browser_download_url', '')
endif
endfor
return ''
endfunction
function! s:download_release() abort function! s:download_release() abort
let l:target = s:target() let l:target = s:target()
if empty(l:target) if empty(l:target)
@@ -56,8 +80,10 @@ function! s:download_release() abort
if !executable('curl') || !executable('tar') if !executable('curl') || !executable('tar')
return 0 return 0
endif endif
let l:url = 'https://code.gfran.co/gffranco/nuwiki/releases/latest/download/nuwiki-ls-' let l:url = s:latest_asset_url('nuwiki-ls-' . l:target . '.tar.gz')
\ . l:target . '.tar.gz' if empty(l:url)
return 0
endif
let l:archive = tempname() . '.tar.gz' let l:archive = tempname() . '.tar.gz'
call system('curl -fsSL -o ' . shellescape(l:archive) . ' ' . shellescape(l:url)) call system('curl -fsSL -o ' . shellescape(l:archive) . ' ' . shellescape(l:url))
if v:shell_error != 0 if v:shell_error != 0