Add autoupdate (#3067)

* add autoupdate.lua

* fetch releases list

* check tar shasum

* get shasum of tags

* update version

* fix current branch

* patch version

* create pr

* fix pr

* add base and head

* fix error

* add verbose

* push commit

* add autoupdate ci
pull/3071/head
ruki 1 year ago committed by GitHub
parent 1847810a6f
commit 6eb115904d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 43
      .github/workflows/autoupdate.yml
  2. 93
      scripts/autoupdate.lua
  3. 113
      scripts/checkupdate.lua

@ -0,0 +1,43 @@
name: Auto-update packages
on:
schedule: # execute every 24 hours
- cron: "0 */24 * * *"
jobs:
build:
strategy:
matrix:
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v1
- uses: xmake-io/github-action-setup-xmake@v1
with:
xmake-version: latest
actions-cache-folder: '.xmake-cache'
- name: Installation
run: |
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
sudo apt update
sudo apt install -y gh unzip zip
echo ${{ secrets.GITHUB_TOKEN }} | gh auth login --with-token
git config --global user.email "waruqi@gmail.com"
git config --global user.name "ruki"
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.SSH_KEY }}
name: id_rsa # optional
known_hosts: ${{ secrets.KNOWN_HOSTS }}
- name: Auto-update packages
run: |
xmake l -vD scripts/autoupdate.lua 1

@ -0,0 +1,93 @@
import("core.package.package")
import("core.base.semver")
import("core.base.hashset")
import("packages", {alias = "packages_util"})
function _load_package(packagename, packagedir, packagefile)
local funcinfo = debug.getinfo(package.load_from_repository)
if funcinfo and funcinfo.nparams == 3 then -- >= 2.7.8
return package.load_from_repository(packagename, packagedir, {packagefile = packagefile})
else
-- deprecated
return package.load_from_repository(packagename, nil, packagedir, packagefile)
end
end
function _get_all_packages()
local packages = _g.packages
if not packages then
packages = {}
for _, packagedir in ipairs(os.dirs(path.join("packages", "*", "*"))) do
local packagename = path.filename(packagedir)
local packagefile = path.join(packagedir, "xmake.lua")
local instance = _load_package(packagename, packagedir, packagefile)
local basename = instance:get("base")
if instance and basename then
local basedir = path.join("packages", basename:sub(1, 1):lower(), basename:lower())
local basefile = path.join(basedir, "xmake.lua")
instance._BASE = _load_package(basename, basedir, basefile)
end
if instance then
table.insert(packages, instance)
end
end
_g.packages = packages
end
return packages
end
function _update_version(instance, version, shasum)
local branch = "autoupdate-" .. instance:name() .. "-" .. version
local branch_current = os.iorun("git branch --show-current"):trim()
local repourl = "https://github.com/xmake-io/xmake-repo.git"
os.vexec("git stash")
os.vexec("git branch -D %s", branch)
os.vexec("git checkout dev")
os.vexec("git pull %s dev", repourl)
os.vexec("git branch %s", branch)
os.vexec("git checkout %s", branch)
local scriptfile = path.join(instance:scriptdir(), "xmake.lua")
if os.isfile(scriptfile) then
local inserted = false
local version_current
io.gsub(scriptfile, "add_versions%(\"(.-)\",%s+\"(.-)\"%)", function (v, h)
if not version_current or sermver.compare(v, version_current) > 0 then
version_current = v
end
if not inserted then
inserted = true
return string.format('add_versions("%s", "%s")\n add_versions("%s", "%s")', version, shasum, v, h)
end
end)
local body = string.format("New version of %s detected (package version: %s, last github version: %s)",
instance:name(), version_current, version)
os.vexec("git add .")
os.vexec("git commit -a -m \"Update %s to %s\"", instance:name(), version)
os.vexec("git push %s %s:%s", repourl, branch, branch)
os.vexec("gh pr create --title \"Auto-update %s to %s\" --body \"%s\" -R xmake-io/xmake-repo -B dev -H %s", instance:name(), version, body, branch)
end
os.vexec("git reset --hard HEAD")
os.vexec("git checkout %s", branch_current)
os.vexec("git stash pop")
end
function main(maxcount)
local count = 0
local maxcount = tonumber(maxcount or 10)
local instances = _get_all_packages()
for _, instance in ipairs(instances) do
local checkupdate_filepath = path.join(instance:scriptdir(), "checkupdate.lua")
if not os.isfile(checkupdate_filepath) then
checkupdate_filepath = path.join(os.scriptdir(), "checkupdate.lua")
end
if os.isfile(checkupdate_filepath) and count < maxcount then
local checkupdate = import("checkupdate", {rootdir = path.directory(checkupdate_filepath), anonymous = true})
local version, shasum = checkupdate(instance)
if version and shasum then
cprint("package(%s): new version ${bright}%s${clear} found, shasum: ${bright}%s", instance:name(), version, shasum)
_update_version(instance, version, shasum)
count = count + 1
end
end
end
end

@ -0,0 +1,113 @@
import("core.base.semver")
import("net.http")
import("devel.git")
import("private.action.require.impl.utils.filter")
function shasum_of(package, url, version)
local shasum
local tmpfile = os.tmpfile()
package:version_set(version)
url = filter.handle(url, package)
local ok = try { function() http.download(url, tmpfile); return true end }
if ok and os.isfile(tmpfile) and os.filesize(tmpfile) > 1024 then
shasum = hash.sha256(tmpfile)
end
os.tryrm(tmpfile)
return shasum
end
function _is_valid_version(version)
if not semver.is_valid(version) then
return false
end
local v = semver.new(version)
local prerelease = v:prerelease()
if prerelease and #prerelease > 0 then
return false
end
return true
end
function _get_version_and_shasum(package, url, version_latest)
if version_latest then
local has_prefix_v = false
for _, version in ipairs(package:versions()) do
if version:startswith("v") then
has_prefix_v = true
end
if semver.compare(version, version_latest) >= 0 then
version_latest = nil
break
end
end
if version_latest then
if has_prefix_v and not version_latest:startswith("v") then
version_latest = "v" .. version_latest
elseif not has_prefix_v and version_latest:startswith("v") then
version_latest = version_latest:sub(2)
end
end
end
if version_latest then
local shasum = shasum_of(package, url, version_latest)
if shasum then
return version_latest, shasum
end
end
end
function _check_version_from_github_tags(package, url)
local repourl = url:match("https://github%.com/.-/.-/")
if repourl then
print("checking version from github tags %s ..", repourl)
local version_latest
local tags = git.tags(repourl)
for _, tag in ipairs(tags) do
if _is_valid_version(tag) and (not version_latest or semver.compare(tag, version_latest) > 0) then
version_latest = tag
end
end
if version_latest then
return _get_version_and_shasum(package, url, version_latest)
end
end
end
function _check_version_from_github_releases(package, url)
local repourl = url:match("https://github%.com/.-/.-/")
if repourl then
print("checking version from github releases %s ..", repourl)
local list = try {function() return os.iorunv("gh", {"release", "list", "--exclude-drafts", "--exclude-pre-releases", "-R", repourl}) end}
if not list then
list = os.iorunv("gh", {"release", "list", "-R", repourl})
end
if list then
local version_latest
for _, line in ipairs(list:split("\n")) do
local splitinfo = line:split("%s+")
local version = splitinfo[#splitinfo - 1]
if version and _is_valid_version(version) then
version_latest = version
break
end
end
if version_latest then
return _get_version_and_shasum(package, url, version_latest)
end
end
end
end
function main(package)
local checkers = {
["https://github%.com/.-/.-/archive/refs/tags/.*"] = _check_version_from_github_tags,
["https://github%.com/.-/.-/releases/download/.*"] = _check_version_from_github_releases
}
for _, url in ipairs(package:urls()) do
for pattern, checker in pairs(checkers) do
if url:match(pattern) then
return checker(package, url)
end
end
end
end
Loading…
Cancel
Save