Files
infix/utils/gh-dl-artifact.sh
T
Mattias Walström 395b21c693 utils/gh-dl-artifact: Accept any prefix for tar.gz package
When brandlabling this may not be infix-, rather vendor-,
 use *- for now.
2025-02-04 19:36:57 +01:00

169 lines
3.5 KiB
Bash
Executable File

#!/bin/sh
set -e
usage()
{
local me="$(basename $0)"
cat <<EOF
usage: $me [<OPTIONS>] [<REV>]
Download the artifact of the specified revision, or HEAD if not
specified, that was built by GitHub's CI action; prepare a new output
tree (by applying the corresponding defconfig); and extract the
artifact.
<REV>
Locate an artifact built from this revision. By default, look for
an artifact built from the current HEAD.
Options:
-a <ARCH>
Locate an artifact built for <ARCH>. By default, look for an
artifact built for the x86_64 architecture.
-b <BR>
Create a new Git branch from <revision> named <BR>, and switch
to it. By default, stay on the current branch if <REV> is
"HEAD", otherwise switch to one named "gh-dl-<REV>".
-h
Show this help message and exit.
-o <OUTPUT-DIR> Prepare the artifact in <OUTPUT-DIR>. By default,
the artifact is extracted in an output directory called
"x-gh-dl-<REV>-<ARCH>".
Examples:
Test the latest image for PR #666:
gh pr checkout 666
$0
cd x-artifact-a1b2c3d4-x86_64
make run
EOF
}
ixdir=$(readlink -f $(dirname "$(readlink -f "$0")")/..)
. $ixdir/board/common/lib.sh
workdir=$(mktemp --tmpdir -d infix-gh-dl-XXXXXXXX)
cleanup()
{
rm -rf $workdir
}
trap cleanup EXIT
topdir=$(git rev-parse --show-toplevel)
apibase="repos/{owner}/{repo}"
arch=x86_64
rev=$(git rev-parse HEAD)
br=
outdir=
# getopt
while getopts "a:b:ho:" opt; do
case ${opt} in
a)
arch="${OPTARG}"
;;
b)
br="${OPTARG}"
;;
h)
usage && exit
;;
o)
outdir="${OPTARG}"
;;
esac
done
shift $((OPTIND - 1))
echo $br
case $# in
0)
;;
1)
rev=$(git rev-parse $1 2>/dev/null || true)
[ "$1" = "HEAD" ] || br=__DEFAULT
;;
*)
usage && exit 1
;;
esac
ixmsg "Locating $arch build of $rev"
sha=$(gh api "$apibase/commits/$rev" -q .sha || die "ERROR: Unknown revision \"$rev\"")
echo "SHA: $sha"
runs=$(gh api "$apibase/actions/runs?head_sha=$sha" \
-q '.workflow_runs[] | .id' | tr '\n' ' ' \
|| die "ERROR: Found no workflow runs associated with $rev")
echo "Runs: $runs"
for run in $runs; do
gh api "$apibase/actions/runs/$run/artifacts" \
-q ".artifacts[] | select(.name == \"artifact-$arch\")" >$workdir/artifact.json \
|| continue
artifact="$(jq .id $workdir/artifact.json)"
[ "$artifact" ] && break
done
[ "$artifact" ] || die "ERROR: Found no $arch artifact associated with any of the runs $runs"
echo "Artifact: $artifact"
url="$(jq -r .archive_download_url $workdir/artifact.json)"
slug=$(echo $sha | head -c 8)
outdir=${outdir:-$topdir/x-gh-dl-$slug-$arch}
imgdir=$outdir/images
if [ "$br" ]; then
if [ "$br" = "__DEFAULT" ]; then
br=gh-dl-$slug
fi
ixmsg "Checking out $slug to branch $br"
if ! git cat-file -e $sha 2>/dev/null; then
echo Artifact is built from $slug, which is not available locally. Updating all remotes...
git remote update
if ! git cat-file -e $sha 2>/dev/null; then
die "ERROR: Unable to locate $slug"
fi
fi
git checkout --recurse-submodules -B $br $sha
fi
ixmsg "Setting up output directory $outdir"
make -C $topdir O=$outdir ${arch}_defconfig
ixmsg "Downloading artifact"
zip=$workdir/zip
gh api $url >$zip
ixmsg "Extracting artifact"
mkdir -p $imgdir
unzip -p $zip "*-${arch}*.tar.gz" | gunzip | tar -C $imgdir -x --strip-components=1
ixmsg "Done"
echo "From $outdir, you can now execute \`make run\`, " \
"\`make test\` etc., using artifact $artifact" | fmt