API for querying package versions (feature request)
I would like the ability to interact with a stable RESTful API to determine versions for packages available for Alpine. For example, if I were to make a request for bash
on x86_64
for v3.17
, it would return 5.2.15-r0
in some format (e.g., a JSON array that one could parse with jq
).
Currently, I'm able to acquire version information by querying pkgs.alpinelinux.org and using an xpath query to extract the version:
url="https://pkgs.alpinelinux.org/packages?name=${package_name}&branch=${branch}&${repo}=&arch=${arch}&maintainer=${maintainer}"
curl -s "$url" | xmllint --html --xpath '//td[@class="version"]/text()' - 2> /dev/null
However, this is a hack and would break if the HTML were to change.
I thought about running apk search -e
on the requested package; however, that would limit the ability to query multiple (branch, architecture, mainntainer) down to a single platform (presumably the one where the command was running). I also considered an over-engineered matrix of Docker images that could be instantiated and queried, but, you know, overhead and such.. Then I thought about some kind of symlink wizardry with the package cache (e.g., a Docker image with the package caches copied onto it; the entrypoint would be passed the details (branch, arch, etc.) and then create a symlink (or move) so that apk search
read for packages on the requested platform (e.g., passing it v3.17 on amd64 would cause apk search
to search on the v3.17 on amd64
packages even though the container's really running on x86_64).
Then I browsed through the apk source in the repo and thought about querying the cached database(s); however, that's really just reinventing the wheel (i.e., apk search
).
I believe that there's likely an API being queried by the site. Maybe what's really needed is some documentation (e.g., add &format=json
to the URL (I'm making this up as an example)). It's also possible that the answer I'm seeking is in a repo somewhere, but I haven't found it (yet). I also searched through the issues here and didn't find what I was looking for.
Also, I looked into Repology and tries to find a nice, clean way of getting where I want to go and I just ran into brick wall after brick wall. I know Renovate is able to query Repology -- I just haven't figured out how they do it (yet).
My use case is that I want the best of both worlds in terms of being able to pin versions of packages in Docker images while not having to go through and figure versions out every time a new minor release of Alpine comes out. I'm getting there by supporting the inclusion of a file called apk.txt
(inspired by Cloud Formation's apt.txt
for Debian packages) which could be iterated through and result in a apk-lock.txt
file (like package.json => package-lock.json for npm). Users of the tool would maintain the apk.txt file, when the tool was run, it would maintain the apk-lock.txt file (which would be checked into the project's repo), and when someone wanted to build an image using pinned package file, they would do something like xargs apk add --no-cache < apk-lock.txt
. My work-in-progress is available on GitHub. Tools like hadolint tend to complain when one runs apk add bash
without the version pinned as pinning versions makes repeatable builds, SBOM, etc. much easier and the resulting images more predictable. However, when something like Dependabot comes along and bumps minor Alpine releases, the package versions often change. Therefore, the workflow for this is Dependabot (or Renovate or whatever) changes the Alpine release and creates a new PR; a "test" for the PR would update the package versions and add the updated pinned package file to the PR, then the rest of the tests would run as usual (the order doesn't matter as much as the changes wind up triggering the workflow to run again). When all of the tests are done, the PR would be buildable without additional human intervention while the packages' versions are pinned in a file that can be inspected. Boom. Best of both worlds.
Anyways, if there's some documentation that needs to be written, I'm happy to do the writing -- I just need to know how to get from here to there.
Thank you for your time and consideration.