arch4edu / aur-auto-update

Automatically update PKGBUILDs on AUR
26 stars 9 forks source link

Add `zapzap-git` #47

Closed alllexx88 closed 6 months ago

alllexx88 commented 6 months ago

I haven't found any examples of using nvchecker with -git AUR packages, so I'm not sure if that's the best solution, but this is the easiest way I could think of: cloning to a temp dir, using git describe and removing the dir.

I first tried a different approach, using github API, with this script (it's not difficult to convert it to a one-liner, a long one :sweat_smile: ):

#!/bin/bash

repo=zapzap-linux/zapzap

tag=$(curl -s "https://api.github.com/repos/$repo/releases/latest" | jq -r '.tag_name')
read type tag_sha < <(echo $(curl -s "https://api.github.com/repos/$repo/git/ref/tags/$tag" |
     jq -r '.object.type,.object.sha'))

if [ $type == "commit" ]; then
    from_sha=$tag_sha
else
    from_sha=$(curl -s "https://api.github.com/repos/$repo/git/tags/$tag_sha" | jq '.object.sha')
fi

commit_history=$(curl -s "https://api.github.com/repos/$repo/commits?sha=main&per_page=100" | jq '.[].sha')

i=1
while ! echo "$commit_history" | grep -qFx $from_sha; do
    i=$(( $i + 1))
    new_commits=$(curl -s "https://api.github.com/repos/$repo/commits?sha=main&per_page=100&page=$i" | jq '.[].sha')
    commit_history=$(echo $commit_history $new_commits | sed -e 's/ /\n/g')
    if [ -z "$new_commits" ]; then
        break
    fi
done

commits_since_release=$(( $(echo "$commit_history" | sed -n "0,/$from_sha/p" | wc -l) - 1 ))

head_sha=$(echo "$commit_history" | head -1 | tr -d '"')

echo ${tag}.r$commits_since_release.g${head_sha:0:7}

But I believe it's more issues prone and is unreadable as a one-liner:

nvchecker:
  source: cmd
  cmd: bash -c 'repo=zapzap-linux/zapzap; tag=$(curl -s "https://api.github.com/repos/$repo/releases/latest" | jq -r ".tag_name"); read type tag_sha < <(echo $(curl -s "https://api.github.com/repos/$repo/git/ref/tags/$tag" | jq -r ".object.type,.object.sha")); if [ $type == "commit" ]; then from_sha=$tag_sha; else from_sha=$(curl -s "https://api.github.com/repos/$repo/git/tags/$tag_sha" | jq ".object.sha"); fi; commit_history=$(curl -s "https://api.github.com/repos/$repo/commits?sha=main&per_page=20" | jq ".[].sha"); i=1; while ! echo "$commit_history" | grep -qFx $from_sha; do i=$(( $i + 1)); new_commits=$(curl -s "https://api.github.com/repos/$repo/commits?sha=main&per_page=20&page=$i" | jq ".[].sha"); commit_history=$(echo $commit_history $new_commits | sed -e "s/ /\n/g"); if [ -z "$new_commits" ]; then break; fi; done; commits_since_release=$(( $(echo "$commit_history" | sed -n "0,/$from_sha/p" | wc -l) - 1 )); head_sha=$(echo "$commit_history" | head -1 | tr -d "\""); echo ${tag}.r$commits_since_release.g${head_sha:0:7}'
test: true

It also quickly reaches rate limits for the github REST API when used few times in a row.

Thanks

petronny commented 6 months ago

Here is the way to track every commit on GitHub:

nvchecker:
  source: github
  github: zapzap-linux/zapzap

However, the bot is not originally developed to update vcs packages since their PKGBUILDs will be automatically updated during builds.

If you feel it's still necessary to do so, please let me know and I need to make some changes to let the bot compatible with vcs packages.

alllexx88 commented 6 months ago

It would be a really awesome feature to support vcs packages.

I'm not familiar with bot internals, and thought it was mandatory to get version from nvchecker exactly as it has to appear on AUR, that it just patches PKGBUILD and .SRCINFO to change the version, but if it could also use pkgver() from PKGBUILD on new commits, it would be great.

Thank you!

alllexx88 commented 6 months ago

Is it an option to use overrides for VCS packages? Something like this:

#!/bin/sh
newver="$1"
force="$2"

get_version () {
    dir=$(mktemp -d -t zapzap-git-XXXXXX)
    [ -d "$dir" ] || (echo "Failed to create tmp dir" && exit 1)
    (cd $dir && git clone https://github.com/zapzap-linux/zapzap && \
        cd zapzap && \
        git describe --long --tags | sed "s/^foo-//;s/\([^-]*-g\)/r\1/;s/-/./g;s/^v//")
    rm -rf $dir
}

newver=`get_version`

[ -z "${newver}" ] && echo "Failed to generate newver." && exit 1

if [ -z "${force}" ]; then
    oldver=$(grep -P '^pkgver=' PKGBUILD | cut -d= -f2)
    [ $(vercmp "${oldver}" "${newver}") -eq 1 ] && echo "The oldver ${oldver} is greater than newver ${newver}." && exit 1
fi

if [ "${oldver}" != "${newver}" ]; then
    sed "s/^pkgver=.*$/pkgver=${newver}/" -i PKGBUILD
    sed "s/^pkgrel=.*$/pkgrel=1/" -i PKGBUILD
fi

#su makepkg -c 'updpkgsums' #  not needed for a VCS package

bin/aur-push has to be slightly fixed to work with VCS packages, since:

$ grep -P '^pkgver' PKGBUILD | cut -d= -f2
5.2.1.r7.g5abbce3
pkgver() {

so we get a broken commit message:

Auto updated to 5.2.1.r7.g5abbce3
pkgver() {

If we add = to the pattern, it works fine:

$ grep -P '^pkgver=' PKGBUILD | cut -d= -f2
5.2.1.r7.g5abbce3

Thanks

petronny commented 6 months ago

Is it an option to use overrides for VCS packages?

Just put the script as pkgbase.override then it will be automatically detected.

And I try to simplify your script as the follow (never tested):

#!/bin/sh
newver="$1" #Just input whatever nvchecker returns, it'll be never used.
force="$2"

if [ -z "${force}" ]; then
  oldver=$(grep -P '^pkgver=' PKGBUILD | cut -d= -f2)
  makepkg -od --noprepare
  newver=$(grep -P '^pkgver=' PKGBUILD | cut -d= -f2)
  [ $(vercmp "${oldver}" "${newver}") -eq 1 ] && echo "The oldver ${oldver} is greater than newver ${newver}." && exit 1
  if [ "${oldver}" != "${newver}" ]; then
    sed "s/^pkgrel=.*$/pkgrel=1/" -i PKGBUILD
  fi
fi

You can use makepkg -od --noprepare to generate new pkgver and also prepare source files. And it seems that nothing is needed to be done when it's a forced update.

bin/aur-push has to be slightly fixed to work with VCS packages

I will add the =.

However, there is a chance that more commits are pushed between the build and push jobs. Then the pkgver will be changed and untested. To avoid this, we need to export the changes as a diff patch at the end of the build job. Then the push job can just apply this patch instead of calling pkgver() again. I'll implement this next week.

alllexx88 commented 6 months ago

Just put the script as pkgbase.override then it will be automatically detected.

Thanks, I understood that from your helpful response in #48 -- I just didn't know if it was a good way to go in this case :sweat_smile:

#!/bin/sh
newver="$1" #Just input whatever nvchecker returns, it'll be never used.
force="$2"

if [ -z "${force}" ]; then
  oldver=$(grep -P '^pkgver=' PKGBUILD | cut -d= -f2)
  makepkg -od --noprepare
  newver=$(grep -P '^pkgver=' PKGBUILD | cut -d= -f2)
  [ $(vercmp "${oldver}" "${newver}") -eq 1 ] && echo "The oldver ${oldver} is greater than newver ${newver}." && exit 1
  if [ "${oldver}" != "${newver}" ]; then
    sed "s/^pkgrel=.*$/pkgrel=1/" -i PKGBUILD
  fi
fi

I tested this locally, against zapzap-git, looks good to me. Maybe just that since you're doing su makepkg -c 'updpkgsums' in https://github.com/arch4edu/aur-auto-update/blob/204cec7eb1a09ea06ec779eb5bdb9bb4d67b1236/bin/update-pkgver#L17 would it be right to do su makepkg -c 'makepkg -od --noprepare' instead of just makepkg -od --noprepare? Is it intended to run makepkg command as makepkg user?

You can use makepkg -od --noprepare to generate new pkgver and also prepare source files.

Good to know, thanks!

And it seems that nothing is needed to be done when it's a forced update.

I'm not sure how forced updates are used right now, but it's possible that upstream gets force pushed to the past, and the current HEAD is older than the current version (or this is also possible if tags naming is broken). Though such cases are pretty rare, and should be handled manually I think.

I will add the =.

Thanks!

However, there is a chance that more commits are pushed between the build and push jobs. Then the pkgver will be changed and untested. To avoid this, we need to export the changes as a diff patch at the end of the build job. Then the push job can just apply this patch instead of calling pkgver() again. I'll implement this next week.

That's very reasonable. I think you've implemented this already in b017b0f, right?

Another silly question. If we get a diff from the build job, does that mean that the build job is mandatory, and test: true isn't needed in the config yaml?

Thanks again :smiley:

petronny commented 6 months ago

would it be right to do su makepkg -c 'makepkg -od --noprepare' instead of just makepkg -od --noprepare? Is it intended to run makepkg command as makepkg user?

Yes, that will be better.

I'm not sure how forced updates are used right now.

A forced update means skipping the version monotonicity check, allowing old version being pushed to AUR. Rarely used.

does that mean that the build job is mandatory, and test: true isn't needed in the config yaml?

Build test is mandatory if the bot wants to push any commit to AUR. #30

If you don't need the bot to push new commits and just want it to flag a package out-of-date, then build test is of course not mandatory. However, this feature hasn't been implemented yet.

alllexx88 commented 6 months ago

Thanks for the clarification @petronny! I've updated the files accordingly.