Sidenote:
I realized it’s been five years since my last post, but oh well better late than never! Hopefully I can update this blog more consistently in the future.
Problem
I’m the maintainer of MbedStudio (an IDE for MbedOS) on AUR (Arch User Repository). However, after moving to NixOS for my daily driver, I have neglected ensuring the package remains in sync with the latest upstream changes.
The update process itself was relatively simple, when there’s a new version I’ll grab the latest tarball path from upstream and update my PKGBUILD (AUR shell script). The PKGBUILD does the patching required when users install it.
Since it is quite straightforward, I decided to automate the maintenance process using GitHub Actions. Here’s how I did it.
1. Patching my PKGBUILD
My original PKGBUILD grabs the archive path as a source and downloads it, verify the checksum before patching and installing effectively pinning it to the “true” version as indicated.
However, for my new PKGBUILD I decided to source the official install script instead, grab the latest tarball path encoded within before downloading and patching. This ensures that the installation would work even if I stopped updating the PKGBUILD.
The caveats are that I have to skip the checksum check for the tarball as the tarball downloaded is no longer “deterministic”.
Diff of the PKGBUILD
- ARCHIVE_PATH="/installers/release-1.4.5/1.4.5.d5955e24/linux/MbedStudio.tar.gz"
+ INSTALLER_PATH="/installers/latest/linux/MbedStudio.sh"
---
- source=("$DOMAIN$ARCHIVE_PATH"
+ source=("$_archivename-official-installer.sh::$DOMAIN$INSTALLER_PATH"
---
+ prepare() {
+ cd "$srcdir"
+ # find archive path
+ ARCHIVE_PATH=$(grep -oP '(?<=ARCHIVE_PATH=).*' $_archivename-official-installer.sh)
+
+ # download archive
+ msg2 "Downloading... $DOMAIN$ARCHIVE_PATH"
+ curl -L -o "$_archivename.tar.gz" "$DOMAIN$ARCHIVE_PATH"
+ }
---
- md5sums=('be7dfb7b3dfda5a35c4552d6e255e33d'
+ md5sums=('SKIP'
you can find the full PKGBUILDs on the AUR repo
Why do I still need Github Actions then?
For MbedStudio the inbuilt updating mechanism does not work with the patch, so to prompt users to update I’ll have to manually bump the version in the PKGBUILD instead.
2. Setting up GitHub Repository
In order to use GitHub Actions, I created a centralized repository for my AUR packages and manage them using aurpublish
.
aurpublish manages all the packages in subdirectories using subtrees.
To pull package maintained
Run the following command at the root of your repo
aurpublish -p <package-name>
To publish package to AUR
Run the following command at the root of your repo
aurpublish <package-name>
Repo Structure
The repository structure should somewhat look like this:
.
├── <package_1_name>
├── <package_2_name>
├── README.md
3 - Creating the GitHub Actions Workflow
Lastly for the actual magic where I automate it! (bumping of the version)
In my repository I created a new directory called .github/workflows
and add a new file named mbed-studio-autoupdate.yml
to create a new GitHub Actions worflow.
mbed-studio-autoupdate.yml
name: Update AUR Package - mbed-studio-bin
on:
schedule:
- cron: '0 0 * * *' # Runs every day at midnight
workflow_dispatch: # Allows manual triggering of the workflow
jobs:
update_version:
runs-on: ubuntu-latest
outputs:
need_update: ${{ steps.check_version.outputs.need_update}}
latest_version: ${{ steps.check_version.outputs.latest_version}}
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Set up Git
run: |
git config --global user.name "${GITHUB_ACTOR}"
git config --global user.email "${GITHUB_ACTOR}@users.noreply.github.com"
- name: Check if update is needed
id: check_version
run: |
cd mbed-studio-bin
# Fetch the latest version from the main website
LATEST_VERSION=$(curl -s https://studio.mbed.com/installers/latest/linux/MbedStudio.sh | grep -oP '(?<=release-)[0-9]+\.[0-9]+\.[0-9]+')
echo "Latest version is $LATEST_VERSION"
# Fetch the current version from PKGBUILD
CURRENT_VERSION=$(grep -oP '(?<=pkgver=)[0-9.]+' PKGBUILD)
echo "Current version is $CURRENT_VERSION"
# Determine if an update is needed
if [ "$LATEST_VERSION" != "$CURRENT_VERSION" ]; then
echo "need_update=true" >> "$GITHUB_OUTPUT"
else
echo "need_update=false" >> "$GITHUB_OUTPUT"
fi
# Save the version information for later steps
echo "latest_version=$LATEST_VERSION" >> "$GITHUB_OUTPUT"
echo "current_version=$CURRENT_VERSION" >> "$GITHUB_OUTPUT"
- name: Update PKGBUILD
if: steps.check_version.outputs.need_update == 'true'
run: |
LATEST_VERSION=${{ steps.check_version.outputs.latest_version }}
cd mbed-studio-bin
# Update pkgver in PKGBUILD and .SRCINFO
sed -i "s/pkgver=.*/pkgver=$LATEST_VERSION/" PKGBUILD
sed -i "s/pkgver=.*/pkgver=$LATEST_VERSION/" .SRCINFO
# Commit and push the changes
git add PKGBUILD .SRCINFO
git commit -m "Update mbed-studio-bin to version $LATEST_VERSION"
git push
- name: upload PKGBUILD for publish_aur job
if: steps.check_version.outputs.need_update == 'true'
uses: actions/upload-artifact@v4
with:
name: PKGBUILD
path: |
mbed-studio-bin/PKGBUILD
publish_aur:
runs-on: ubuntu-latest
needs: update_version
if: needs.update_version.outputs.need_update == 'true'
steps:
- name: Download PKGBUILD from update_version job
uses: actions/download-artifact@v4
with:
name: PKGBUILD
- name: Publish AUR package
uses: ulises-jeremias/github-actions-aur-publish@v1
with:
pkgname: mbed-studio-bin
pkgbuild: ./PKGBUILD
commit_username: ${{ secrets.AUR_USERNAME }}
commit_email: ${{ secrets.AUR_EMAIL }}
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
commit_message: v${{ needs.update_version.outputs.latest_version }}
ssh_keyscan_types: rsa,ed25519
update_pkgver: false
The workflow is divided into two jobs, one that patches the PKGBUILD on github and another that publishes it to AUR if a patch is done.
This is mainly done as the extension aur-publish
takes awhile to build a container at each job invocation, wasting precious Actions minutes.
Note:
aur-publish
is different from aurpublish
aurpublish
is a tool that manages my repository locally which couldn’t really be ran on Github Actions.aur-publish
is a GitHub Actions extension that simplifies the publishing of a PKGBUILD to AUR.
Final Thoughts
And that’s pretty much it! An afternoon worth of work.
Technically a more ideal solution would be to:
- grab the latest tarball path and update in PKGBUILD
- download the tarball, calculate checksum and update in the PKGBUILD
- build it with
makepkg
to ensure it works.
However that approach would use too much Github Actions minutes for my liking.
Regardless, this process of automating the package management should still serve as a useful starting point for anyone attempting do something similar :)
On another note, I might try to maintain more packages in the future, either on the AUR or some Nix packages (which I’m still trying to figure out).