Compare commits

...

1 Commits

Author SHA1 Message Date
Dmitriy Kovalenko f3a46a068b Prebuild binaries
Prebuild / Build aarch64-apple-darwin (push) Has been cancelled
Prebuild / Build aarch64-pc-windows-msvc (push) Has been cancelled
Prebuild / Build aarch64-unknown-linux-gnu (push) Has been cancelled
Prebuild / Build aarch64-unknown-linux-musl (push) Has been cancelled
Prebuild / Build x86_64-apple-darwin (push) Has been cancelled
Prebuild / Build x86_64-pc-windows-msvc (push) Has been cancelled
Prebuild / Build x86_64-unknown-linux-gnu (push) Has been cancelled
Prebuild / Build x86_64-unknown-linux-musl (push) Has been cancelled
Prebuild / Release (push) Has been cancelled
2025-09-16 17:53:58 +02:00
5 changed files with 296 additions and 27 deletions
+41 -24
View File
@@ -1,9 +1,8 @@
name: Release
name: Prebuild
on:
push:
tags:
- "v*"
branches: [main, feat/prebuild]
jobs:
build:
@@ -18,44 +17,47 @@ jobs:
# Glibc 2.21
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
artifact_name: target/x86_64-unknown-linux-gnu/release/libfff_fuzzy.so
artifact_name: target/x86_64-unknown-linux-gnu/release/libfff_nvim.so
- os: ubuntu-latest
target: aarch64-unknown-linux-gnu
artifact_name: target/aarch64-unknown-linux-gnu/release/libfff_fuzzy.so
artifact_name: target/aarch64-unknown-linux-gnu/release/libfff_nvim.so
# Musl 1.2.3
- os: ubuntu-latest
target: x86_64-unknown-linux-musl
artifact_name: target/x86_64-unknown-linux-musl/release/libfff_fuzzy.so
artifact_name: target/x86_64-unknown-linux-musl/release/libfff_nvim.so
- os: ubuntu-latest
target: aarch64-unknown-linux-musl
artifact_name: target/aarch64-unknown-linux-musl/release/libfff_fuzzy.so
# Android (Termux)
- os: ubuntu-latest
target: aarch64-linux-android
artifact_name: target/aarch64-linux-android/release/libfff_fuzzy.so
artifact_name: target/aarch64-unknown-linux-musl/release/libfff_nvim.so
# # Android (Termux)
# - os: ubuntu-latest
# target: aarch64-linux-android
# artifact_name: target/aarch64-linux-android/release/libfff_nvim.so
## macOS builds
- os: macos-latest
target: x86_64-apple-darwin
artifact_name: target/x86_64-apple-darwin/release/libfff_fuzzy.dylib
artifact_name: target/x86_64-apple-darwin/release/libfff_nvim.dylib
- os: macos-latest
target: aarch64-apple-darwin
artifact_name: target/aarch64-apple-darwin/release/libfff_fuzzy.dylib
artifact_name: target/aarch64-apple-darwin/release/libfff_nvim.dylib
## Windows builds
- os: windows-latest
target: x86_64-pc-windows-msvc
artifact_name: target/x86_64-pc-windows-msvc/release/fff_fuzzy.dll
artifact_name: target/x86_64-pc-windows-msvc/release/fff_nvim.dll
- os: windows-latest
target: aarch64-pc-windows-msvc
artifact_name: target/aarch64-pc-windows-msvc/release/fff_nvim.dll
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Set Rust toolchain
if: contains(matrix.target, 'linux')
# https://github.com/rust-cross/cargo-zigbuild/issues/327
run: echo -e '[toolchain]\nchannel = "nightly-2025-02-19"' > rust-toolchain.toml
# - name: Set Rust toolchain
# if: contains(matrix.target, 'linux')
# # https://github.com/rust-cross/cargo-zigbuild/issues/327
# run: echo -e '[toolchain]\nchannel = "nightly-2025-02-19"' > rust-toolchain.toml
- name: Install Rust
run: |
@@ -88,7 +90,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.target }}
path: ${{ matrix.target }}.*
path: ${{ matrix.target }}*
release:
name: Release
@@ -97,22 +99,37 @@ jobs:
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Download artifacts
uses: actions/download-artifact@v4
with:
path: ./binaries
- name: Generate checksums
working-directory: ./binaries
run: |
ls -a
for file in ./**/*; do
sha256sum "$file" > "${file}.sha256"
done
- name: Prepare tag
id: vars
shell: bash
run: |
sha="$(git rev-parse --short HEAD)"
echo "tag=$sha" >> $GITHUB_OUTPUT
- name: Upload Release Assets
uses: softprops/action-gh-release@v2
with:
name: ${{ github.ref_name }}
tag_name: ${{ github.ref_name }}
name: "${{ steps.vars.outputs.tag }}"
tag_name: "${{ steps.vars.outputs.tag }}"
token: ${{ github.token }}
files: ./**/*
files: ./binaries/**/*
draft: false
prerelease: false
generate_release_notes: true
prerelease: true
generate_release_notes: false
body: |
Nightly release from commit: ${{ github.sha }}
+6 -2
View File
@@ -49,8 +49,12 @@ FFF.nvim requires:
```lua
{
'dmtrKovalenko/fff.nvim',
build = 'cargo build --release',
-- or if you are using nixos
build = function()
-- this will download prebuild binary or try to use existing rustup toolchain to build from source
-- (if you are using lazy you can use gb for rebuilding a plugin if needed)
require("fff.download").download_or_build_binary()
end,
-- if you are using nixos
-- build = "nix run .#release",
opts = { -- (optional)
debug = {
+190
View File
@@ -0,0 +1,190 @@
local M = {}
local system = require('fff.utils.system')
local uv = vim and vim.uv or require('luv')
local GITHUB_REPO = 'dmtrKovalenko/fff.nvim'
local function get_current_version(plugin_dir, callback)
vim.system({ 'git', 'rev-parse', '--short', 'HEAD' }, { cwd = plugin_dir }, function(result)
if result.code ~= 0 or not result.stdout or result.stdout == '' then
callback(nil)
return
end
callback(result.stdout:gsub('%s+', ''))
end)
end
local function get_binary_dir(plugin_dir) return plugin_dir .. '/../target' end
local function get_binary_path(plugin_dir)
local binary_dir = get_binary_dir(plugin_dir)
local extension = system.get_lib_extension()
return binary_dir .. '/libfff_nvim.' .. extension
end
local function binary_exists(plugin_dir)
local binary_path = get_binary_path(plugin_dir)
local stat = uv.fs_stat(binary_path)
return stat and stat.type == 'file'
end
local function download_file(url, output_path, opts, callback)
opts = opts or {}
local dir = vim.fn.fnamemodify(output_path, ':h')
uv.fs_mkdir(dir, 493, function(err) -- 493 = 0755 octal
if err and not err:match('EEXIST') then
callback(false, 'Failed to create directory: ' .. err)
return
end
local curl_args = {
'curl',
'--fail',
'--location',
'--silent',
'--show-error',
'--output',
output_path,
}
if opts.proxy then
table.insert(curl_args, '--proxy')
table.insert(curl_args, opts.proxy)
end
table.insert(curl_args, url)
vim.system(curl_args, {}, function(result)
if result.code ~= 0 then
callback(false, 'Failed to download: ' .. (result.stderr or 'unknown error'))
return
end
callback(true, nil)
end)
end)
end
local function download_from_github(version, binary_path, opts, callback)
opts = opts or {}
local triple = system.get_triple()
local extension = system.get_lib_extension()
local binary_name = triple .. '.' .. extension
local url = string.format('https://github.com/%s/releases/download/%s/%s', GITHUB_REPO, version, binary_name)
vim.schedule(function()
vim.notify(string.format('Downloading fff.nvim binary for ' .. version), vim.log.levels.INFO)
vim.notify(string.format('Do not open fff until you see a success notification.'), vim.log.levels.WARN)
end)
download_file(url, binary_path, {
proxy = opts.proxy,
extra_curl_args = opts.extra_curl_args,
}, function(success, err)
if not success then
callback(false, err)
return
end
-- Verify the binary can be loaded
local ok, err_msg = pcall(function() package.loadlib(binary_path, 'luaopen_fff_nvim') end)
if not ok then
uv.fs_unlink(binary_path)
callback(false, 'Downloaded binary is not valid: ' .. (err_msg or 'unknown error'))
return
end
vim.schedule(function() vim.notify('fff.nvim binary downloaded successfully!', vim.log.levels.INFO) end)
callback(true, nil)
end)
end
function M.ensure_downloaded(opts, callback)
opts = opts or {}
local plugin_dir = vim.fn.fnamemodify(debug.getinfo(1, 'S').source:sub(2), ':h:h')
if binary_exists(plugin_dir) and not opts.force then
callback(true, nil)
return
end
local function on_version(target_version)
if not target_version then
callback(false, 'Could not determine target version')
return
end
local binary_path = get_binary_path(plugin_dir)
download_from_github(target_version, binary_path, opts, callback)
end
if opts.version then
on_version(opts.version)
else
get_current_version(plugin_dir, on_version)
end
end
function M.download_binary(callback)
M.ensure_downloaded({ force = true }, function(success, err)
if not success then
if callback then
callback(false, err)
else
error('Failed to download fff.nvim binary: ' .. (err or 'unknown error'))
end
return
end
if callback then callback(true, nil) end
end)
end
function M.build_binary(callback)
local plugin_dir = vim.fn.fnamemodify(debug.getinfo(1, 'S').source:sub(2), ':h:h')
local has_rustup = vim.fn.executable('rustup') == 1
if not has_rustup then
callback(
false,
'rustup is not found. It is required to build the fff.nvim binary. Install it from https://rustup.rs/'
)
return
end
vim.system({ 'cargo', 'build', '--release' }, { cwd = plugin_dir }, function(result)
if result.code ~= 0 then
callback(false, 'Failed to build rust binary: ' .. (result.stderr or 'unknown error'))
return
end
callback(true, nil)
end)
end
function M.download_or_build_binary()
M.ensure_downloaded({ force = true }, function(download_success, download_error)
if download_success then return end
vim.schedule(
function()
vim.notify(
'Error downloading binary: ' .. (download_error or 'unknown error') .. '\nTrying cargo build --release\n',
vim.log.levels.WARN
)
end
)
M.build_binary(function(build_success, build_error)
if not build_success then
error('Failed to build fff.nvim binary. Build error: ' .. (build_error or 'unknown error'))
else
vim.schedule(function() vim.notify('fff.nvim binary built successfully!', vim.log.levels.INFO) end)
end
end)
end)
end
function M.get_binary_path()
local plugin_dir = vim.fn.fnamemodify(debug.getinfo(1, 'S').source:sub(2), ':h:h')
return get_binary_path(plugin_dir)
end
return M
+4 -1
View File
@@ -1,3 +1,5 @@
local download = require('fff.download')
--- @return string
local function get_lib_extension()
if jit.os:lower() == 'mac' or jit.os:lower() == 'osx' then return '.dylib' end
@@ -10,6 +12,7 @@ end
local base_path = debug.getinfo(1).source:match('@?(.*/)')
local paths = {
download.get_binary_path(),
base_path .. '../../../target/release/lib?' .. get_lib_extension(),
base_path .. '../../../target/release/?' .. get_lib_extension(),
}
@@ -24,7 +27,7 @@ package.cpath = package.cpath .. ';' .. table.concat(paths, ';')
local ok, backend = pcall(require, 'fff_nvim')
if not ok then
error('Failed to load fff rust backend. Make sure that it has been built with `cargo build --release`')
error('Failed to load fff rust backend. Make sure that it has been downloaded or built with `cargo build --release`')
end
return backend
+55
View File
@@ -0,0 +1,55 @@
local M = {}
local uv = vim and vim.uv or require('luv')
-- Get the system triple (target triple for the current platform)
function M.get_triple()
local os_name = uv.os_uname().sysname:lower()
local arch = uv.os_uname().machine:lower()
-- Normalize OS name
if os_name == 'darwin' then
os_name = 'apple-darwin'
elseif os_name == 'linux' then
-- Detect if we're on musl or glibc
local handle = io.popen('ldd --version 2>&1')
if handle then
local output = handle:read('*a')
handle:close()
if output and output:match('musl') then
os_name = 'unknown-linux-musl'
else
os_name = 'unknown-linux-gnu'
end
else
os_name = 'unknown-linux-gnu'
end
elseif os_name:match('windows') or os_name:match('mingw') or os_name:match('msys') then
os_name = 'pc-windows-msvc'
end
-- Normalize architecture
if arch == 'x86_64' or arch == 'amd64' then
arch = 'x86_64'
elseif arch == 'aarch64' or arch == 'arm64' then
arch = 'aarch64'
elseif arch:match('^arm') then
arch = 'arm'
end
return arch .. '-' .. os_name
end
-- Get the library extension for the current platform
function M.get_lib_extension()
local os_name = uv.os_uname().sysname:lower()
if os_name == 'darwin' then
return 'dylib'
elseif os_name:match('windows') or os_name:match('mingw') or os_name:match('msys') then
return 'dll'
else
return 'so'
end
end
return M