Skip to content

Commit

Permalink
add pack script
Browse files Browse the repository at this point in the history
optimize

fix

fix

build with version

Update publish.yml

fix build

impl pack ipk
  • Loading branch information
LazuliKao committed Oct 1, 2024
1 parent e11eb40 commit b297b0d
Show file tree
Hide file tree
Showing 14 changed files with 342 additions and 2 deletions.
40 changes: 40 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: publish

on:
push:

permissions:
contents: write

jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Set up .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.x

- name: Build
run:
dotnet fsi ./tools/pack.fsx -v ${{ github.ref_name }}

# upload artifacts
- name: Upload Release Asset
uses: actions/upload-artifact@v4
with:
path: dist/*

- name: Create Release
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
files: dist/*
tag_name: ${{ github.ref_name }}
generate_release_notes: true

2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@

tools/connection.json
/downloads
/dist
12 changes: 12 additions & 0 deletions control/control
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Package: luci-app-nbtverify
Version: 1.0
Depends: +ipset +dnsmasq-full +curl
Source: https://github.com/nbtca/luci-app-nbtverify
SourceName: luci-app-nbtverify
License: GPL-2.0
Section: luci
SourceDateEpoch: 1644683634
Maintainer: nbtca <https://github.com/nbtca>
Architecture: x86_64
Description: LuCI Support for nbtverify
# Installed-Size: 1268
5 changes: 5 additions & 0 deletions control/postinst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/sh
[ "${IPKG_NO_SCRIPT}" = "1" ] && exit 0
[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0
. ${IPKG_INSTROOT}/lib/functions.sh
default_postinst $0 $@
4 changes: 4 additions & 0 deletions control/postinst-pkg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[ -n "${IPKG_INSTROOT}" ] || {
(. /etc/uci-defaults/luci-app-nbtverify) && rm -f /etc/uci-defaults/luci-app-nbtverify
exit 0
}
4 changes: 4 additions & 0 deletions control/prerm
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0
. ${IPKG_INSTROOT}/lib/functions.sh
default_prerm $0 $@
4 changes: 4 additions & 0 deletions tools/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[*.{fs,fsx}]
fsharp_newline_between_type_definition_and_members = false
fsharp_blank_lines_around_nested_multiline_expressions = false
fsharp_newline_before_multiline_computation_expression = false
13 changes: 13 additions & 0 deletions tools/.idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions tools/.idea/encodings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions tools/.idea/indexLayout.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions tools/.idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

82 changes: 82 additions & 0 deletions tools/github_release.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#r "nuget: Octokit, 13.0.1"
#r "nuget: Downloader, 3.2.0"
open Downloader
open System.IO
let client = new Octokit.GitHubClient(new Octokit.ProductHeaderValue("nbtca"))
let download (url: string) (saveTo: string) onProgress =
let downloadOpt =
new DownloadConfiguration(
ChunkCount = 8, // file parts to download, the default value is 1
ParallelDownload = true // download parts of the file as parallel or not. The default value is false
)
let service = new DownloadService(downloadOpt)
service.DownloadProgressChanged.AddHandler(fun _ e -> onProgress e)
service.DownloadFileTaskAsync(url, saveTo, Unchecked.defaultof<System.Threading.CancellationToken>)
let formatByteSize (size: int64) =
let rec formatSize size suffixes =
match size, suffixes with
| size, [] -> size, ""
| size, suffix :: suffixes ->
if size < 1024.0 then
size, suffix
else
formatSize (size / 1024.0) suffixes
let size, suffix =
formatSize (float size) [ "B"; "KB"; "MB"; "GB"; "TB"; "PB"; "EB"; "ZB"; "YB" ]
sprintf "%0.2f %s" size suffix
// let downloadItem()=
let fetchReleaseFiles owner repo = task {
printfn "Fetching latest release for %s/%s" owner repo
let! info = client.Repository.Release.GetLatest(owner, repo)
let assets = info.Assets
let rootDownload =
Path.Combine(__SOURCE_DIRECTORY__ |> Path.GetDirectoryName, "downloads")
printfn "Downloading %s" info.TagName
let downloadDir = Path.Combine(rootDownload, info.TagName)
Directory.CreateDirectory(downloadDir) |> ignore
let files =
[ for asset in assets do
let downloadUrl = asset.BrowserDownloadUrl
let fileName = asset.Name
let saveTo = Path.Combine(downloadDir, fileName)
(fileName, downloadUrl, saveTo) ]
let lockx = obj ()
let mutable progress =
[| for fileName, _, _ in files -> sprintf "Fetching %s ..." fileName |]
let cts = new System.Threading.CancellationTokenSource()
let baseI = System.Console.CursorTop
let progressTask = task {
while not cts.Token.IsCancellationRequested do
lock lockx (fun _ ->
let ci = System.Console.CursorTop
System.Console.CursorTop <- baseI
System.Console.CursorLeft <- 0
for i in 0 .. progress.Length - 1 do
printfn "%s" progress.[i]
System.Console.CursorTop <- ci)
do! System.Threading.Tasks.Task.Delay(1000)
}
let! _ =
files
|> List.mapi (fun i (fileName, downloadUrl, saveTo) ->
(async {
if saveTo |> File.Exists then
progress[i] <- sprintf "Skipping %s" fileName
else
progress[i] <- sprintf "Downloading %s" fileName
do!
download downloadUrl saveTo (fun e ->
progress[i] <-
sprintf
"Downloading %s: %s/%s"
fileName
(formatByteSize e.ReceivedBytesSize)
(formatByteSize e.TotalBytesToReceive))
|> Async.AwaitTask
printfn "Downloaded %s" fileName
}))
|> Async.Parallel
cts.Cancel()
do! progressTask
return files
}
156 changes: 156 additions & 0 deletions tools/pack.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
#r "nuget: SharpCompress, 0.38.0"
#r "nuget: Octokit, 13.0.1"
#r "nuget: CommandLineParser.FSharp, 2.9.1"
#load "./github_release.fsx"
open System.IO
open SharpCompress.Writers.Tar
open SharpCompress.Readers.Tar
open SharpCompress.Common
open System
open CommandLine
open System.Collections.Generic
let mutable version = "1.0"
[<CLIMutable>]
type options =
{ [<Option('v', "version", Required = false, HelpText = "Version")>]
version: string }
let argv =
Environment.GetCommandLineArgs()
|> Array.skip 1
|> Array.skipWhile (fun x -> x.EndsWith(".fsx"))
printfn "Args: %A" argv
let result = CommandLine.Parser.Default.ParseArguments<options>(argv)
let run (o: options) =
printfn "Parser success"
version <- o.version.TrimStart('v')
printfn "version = %s" version
let fail (e: IEnumerable<Error>) = failwithf "Parser failed with %A" e
match result with
| :? Parsed<options> as parsed -> run parsed.Value
| :? NotParsed<options> as notParsed -> fail notParsed.Errors
| _ -> ()

let toUnixRelativePath root file =
"./"
+ Path.GetRelativePath(root, file).Replace(Path.DirectorySeparatorChar, '/')
let createTarGz output root files (replacements: Collections.Generic.IDictionary<string, byte[]>) =
use writer = new TarWriter(output, TarWriterOptions(CompressionType.GZip, true))
let fixPath = toUnixRelativePath root
List.sum
[ for file in files do
let relativePath = fixPath file
let find, data = replacements.TryGetValue(relativePath)
if find then
printfn "Replacing %s" relativePath
use newStream = new MemoryStream(data)
writer.Write(relativePath, newStream, DateTime.Now)
data.LongLength
else
printfn "Packing %s" relativePath
let fileInfo = FileInfo(file)
use fileStream = fileInfo.OpenRead()
writer.Write(relativePath, fileStream, fileInfo.LastWriteTime)
fileInfo.Length ]
let git = Path.GetDirectoryName(__SOURCE_DIRECTORY__)

let tarFiles stream root replacements =
createTarGz
stream
(Path.GetFullPath(root))
(Directory.EnumerateFiles(root, "*", SearchOption.AllDirectories))
replacements
let toBytes (s: string) =
s
|> _.Trim()
|> _.Replace("\r", "")
|> fun x -> x + "\n" |> Text.Encoding.UTF8.GetBytes
let pack bin arch outputFile =
use data = new MemoryStream()
let installSize =
dict [ "./usr/bin/nbtverify", bin ]
|> tarFiles data (Path.Combine(git, "files"))
use control = new MemoryStream()
[ "./control",
$"""
Package: luci-app-nbtverify
Version: {version}
Depends: luci-compat
Source: https://github.com/nbtca/luci-app-nbtverify
SourceName: luci-app-nbtverify
License: GPL-2.0
Section: luci
SourceDateEpoch: {DateTimeOffset.Now.ToUnixTimeSeconds()}
Maintainer: nbtca <https://github.com/nbtca>
Architecture: {arch}
Description: LuCI Support for nbtverify
Installed-Size: {installSize}
"""
|> toBytes ]
|> dict
|> tarFiles control (Path.Combine(git, "control"))
|> ignore
use output = File.Create(outputFile)
use writer = new TarWriter(output, TarWriterOptions(CompressionType.GZip, true))
use info = new MemoryStream(Text.Encoding.UTF8.GetBytes("2.0\n"))
writer.Write("./debian-binary", info, DateTime.Now)
data.Position <- 0L
writer.Write("./data.tar.gz", data, DateTime.Now)
control.Position <- 0L
writer.Write("./control.tar.gz", control, DateTime.Now)
printfn "Package created at %s" outputFile
// pack ("x86_64")
let fetchReleaseFiles () = task {
let! files = Github_release.fetchReleaseFiles "nbtca" "nbtverify"
return
files
|> List.filter (fun (fileName, _, _) -> fileName.EndsWith ".tar.gz")
|> List.map (fun (_, _, filePath) ->
let info =
filePath
|> Path.GetFileNameWithoutExtension
|> _.Split([| "_"; "." |], StringSplitOptions.RemoveEmptyEntries)
let system = info[1]
let arch = info[2]
(filePath, system, arch))
|> List.filter (fun (_, system, _) -> system = "linux")
|> List.map (fun (filePath, _, arch) -> (filePath, arch))
}
let files = fetchReleaseFiles () |> Async.AwaitTask |> Async.RunSynchronously
//ref https://openwrt.org/docs/techref/targets/start
let openwrtArchMap =
dict
[ "386", [ "i386_pentium4" ]
"amd64", [ "x86_64" ]
"arm", [ "arm_cortex-a9" ]
"arm64", [ "aarch64_generic" ]
"mips64", [ "mips64_mips64" ]
"mips64le", [ "mips64el_mips64" ]
"mipsle", [ "mipsel_mips32"; "mipsel_24kc"; "mipsel_74kc" ]
"mips", [ "mips_mips32"; "mips_24kc"; "mips_4kec" ]
// "riscv64",""
]
let unpack tarFile =
use stream = File.OpenRead(tarFile)
use reader = TarReader.Open(stream)
//extract only nbtverify__darwin_arm64\nbtverify
use memoryStream = new MemoryStream()
while reader.MoveToNextEntry() do
let entry = reader.Entry
if entry.IsDirectory |> not then
let path = entry.Key
let filename = path |> Path.GetFileName
if filename = "nbtverify" then
printfn "Extracting %s" filename
reader.WriteEntryTo(memoryStream)
memoryStream.ToArray()
let dist = Path.Combine(git, "dist")
Directory.CreateDirectory(dist) |> ignore
for filePath, arch in files do
let exists, targets = openwrtArchMap.TryGetValue(arch)
if exists then
for target in targets do
let outputFile = Path.Combine(dist, $"luci-app-nbtverify_{arch}_{target}.ipk")
pack (filePath |> unpack) target outputFile
printfn "Packing %A" target
else
printfn "Arch %A not supported" arch
4 changes: 2 additions & 2 deletions tools/sync.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ let saveConnectionInfo (info: ConnectionInfo) =
let json =
JsonSerializer.Serialize(info, JsonSerializerOptions(WriteIndented = true))

System.IO.File.WriteAllText(configFile, json)
File.WriteAllText(configFile, json)


let connectionInfo =
match System.IO.File.Exists configFile with
match File.Exists configFile with
| true -> readConnectionInfo ()
| false ->
{ Host = "localhost"
Expand Down

0 comments on commit b297b0d

Please sign in to comment.