Skip to content

Instantly share code, notes, and snippets.

@jbenner-radham
Last active August 4, 2025 21:21
Show Gist options
  • Save jbenner-radham/17ba544fcf0c7443cca18502e6eb5af5 to your computer and use it in GitHub Desktop.
Save jbenner-radham/17ba544fcf0c7443cca18502e6eb5af5 to your computer and use it in GitHub Desktop.
Notes regarding random thoughts about GitHub releases and the retrieval of them via POSIX script.

Get the Latest Release Tag (Without the GitHub API)

# Yes, I know that cURL isn't part of POSIX but it's pretty ubiquitous. Maybe see if a Wget fallback would be possible? (note: Apparently Wget is not installed on macOS by default)
# The alternative to use cURL (or possibly Wget) is to use the Git "sparse checkout" technique I'm currently utilizing. Yet again, not POSIX. And probably pre-installed on less UNIX-like operating systems than cURL or Wget.
LATEST_RELEASE=$(basename $(curl --head --location --output /dev/null --silent --write-out %{url_effective} https://github.com/jbenner-radham/node-readme-md-cli/releases/latest))

# After messing around with it for a bit, here's a potential Wget (and grep and sed) based alternative.
# So why is `grep` in there you ask? Well apparently `sed` cannot do multiline regex (at least through pipes). So it's just there to get that "Location" header line for `sed` to extract from.
# Also, `sed` uses "basic regular expressions" (apparently "modern regular expressions" are a non-standard extension) which means that the capturing group has to be escaped (e.g., `\(.*\)`)
# Just found out that macOS implemented `sed -r` for GNU sed compatability. So the `sed` part of the pipe could potentially be: `sed -r 's/^Location: (.*) \[following\]$/\1/'` instead.
LATEST_RELEASE=$(basename $(wget --spider --tries 1 https://github.com/jbenner-radham/node-readme-md-cli/releases/latest 2>&1 | grep 'Location: ' | sed 's/^Location: \(.*\) \[following\]$/\1/'))

# The new versions of Fedora ship with Wget2 instead of Wget. Wget2 is interesting... it doesn't display location headers in addition to other oddities. But, I figured something out.
LATEST_RELEASE=$(basename $(wget2 --method HEAD --output-document /dev/null --stats-site human:- --tries 1 --quiet https://github.com/jbenner-radham/node-readme-md-cli/releases/latest | tail -n 1) | tail -n 1)

# Okay, so HTTPie is **DEFINITELY** not in POSIX... but I was curious so here's what I came up with.
LATEST_RELEASE=$(basename $(http --headers https://github.com/jbenner-radham/node-readme-md-cli/releases/latest | grep 'Location: ' | sed -r 's/^Location: (.+)$/\1/'))

# Yet again, not POSIX (especially since we're adding `jq` to the mix). But I thought this curiosity was worth documenting.
# GitHub supports HTTP content negotiation, so requesting a JSON version of a page will give you a JSON representation.
# I would hope they don't rate limit this like they do with their API, but you never know. So I wouldn't rely on it without testing.
LATEST_RELEASE=$(http --body --follow https://github.com/jbenner-radham/node-readme-md-cli/releases/latest Accept:application/json | jq --raw-output .tag_name)

# Or if needed, without the "v" prefix...
UNPREFIXED_LATEST_RELEASE="${LATEST_RELEASE#v}"

Get the Version From a Release Artifact

cat dist/theme.yml | head -n 1 | sed 's/^# Belmont Theme for Eza v\(.*\)$/\1/'

Extract Major, Minor, and Patch From Version

# Using sed.
MAJOR_MINOR_VERSION=$(echo "0.1.2" | sed 's/^\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)$/\1\.\2/')
PATCH_VERSION=$(echo "0.1.2" | sed 's/^\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)$/\3/')

# Using cut (this appears to be POSIX, but double check.) Of note, cut is 1 indexed instead of 0 indexed.
MAJOR_MINOR_VERSION=$(echo "0.10.2" | cut -d . -f 1,2)
PATCH_VERSION=$(echo "0.10.2" | cut -d . -f 3)

Compare Versions

if [ $INSTALLED_MAJOR_MINOR_VERSION -lt $LATEST_MAJOR_MINOR_VERSION ]; then
  # Update...
elif [ $INSTALLED_MAJOR_MINOR_VERSION = $LATEST_MAJOR_MINOR_VERSION ] && [ $INSTALLED_PATCH_VERSION -lt $LATEST_PATCH_VERSION ]; then
  # Update
else
  # Don't Update
fi

Creating a Compressed Release Artifact (Consisting of One File)

# Creating a zip.
# The `zip` command is not listed as being part of POSIX in it's man page. That's probably not a problem for *creating* release artifacts though.
zip theme.zip theme.yaml

# Creating a gzipped tarball.
# Surprisingly `tar` is apparently not currently a part of POSIX. Looks like it was added to the standard in 1996, but then removed from it in 2001. Yet again, that's probably not a problem for *creating* release artifacts though.
# Listing what the flag names mean below. I would use the long flags for clarity (e.g., `--create` over `-c`), but they don't seem to be portable across operating systems in all cases.
# * The `-c` flag stands for "create"
# * The `-z` flag stands for "gzip" (or "gunzip" depending on the context)
# * The `-f` flag stands for "file" and requires a specified filename argument.
tar -czf theme.tar.gz theme.yaml

Extracting a Compressed Release Artifact (Consisting of One File)

# Unzipping a file to the current directory.
# * The `-q` flag stands for "quiet" and just means do not echo out the extracted file names
unzip -q theme.zip

# Alternatively, unzipping to a different directory.
# * The `-d` flag stands for "directory" or more specifically the extraction directory.
unzip -qd "${EZA_CONFIG_DIR}" theme.zip

# Extracting a gzipped tarball to the current directory.
# * The `-x` flag stands for "extract"
# * The `-z` flag stands for "gunzip" (or "gzip" depending on the context)
# * The `-f` flag stands for "file" and requires a specified filename argument.
tar -xzf theme.tar.gz

# Alternatively, gunzipping to a different directory.
# * The `-C` flag stands for "change" (as in "change directory") and it signifies that `tar` should change directories after opening the archive but before extracting.
tar -xzf theme.tar.gz -C "${EZA_CONFIG_DIR}"

File Sizes

Interestingly, at least in the case of a singular YAML file Zip has better compression than GZip (although nothing crazy).

  • theme.yaml: 5.9k
  • theme.tar.gz: 1.7k
  • theme.zip: 1.5k

Potential Release Filenames

  • belmont-theme-for-eza-0.1.0.zip
  • belmont-theme-for-eza-0.1.0.tar.gz

Maybe offer just a pure YAML download too?

  • belmont-theme-for-eza-0.1.0.yaml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment