Skip to content

install on linux with one line - #62

Merged
jonhadfield merged 1 commit into
mainfrom
feature/linux-install-script
Sep 5, 2026
Merged

jonhadfield merged 1 commit into
mainfrom
feature/linux-install-script

Conversation

@jonhadfield

Copy link
Copy Markdown
Owner

There was no way to install on Linux short of finding the right archive on the releases page, unpacking it and moving the binary somewhere.

curl -sL https://raw.githubusercontent.com/jonhadfield/certreader/main/install | sh

Works out the latest release, downloads the archive for the machine it runs on, and installs to /usr/local/bin.

differences from ipscout's script

It keeps the same shape and [n/n] output, but is deliberately not a copy:

  • It verifies the download against the sums published beside it, and installs nothing if they disagree. That is the one thing a script piped into a shell should not skip.
  • ipscout's tests uname against "darwin" where uname says Darwin, so under set -e that failed test ends the script on macOS before it installs anything.
  • ipscout's unpacks into whatever directory it was run from and leaves the binary there. This one works in a temp dir removed on exit.

certreader's archives also carry the version in the filename, so releases/latest/download/... does not resolve. The version comes from following the redirect /releases/latest answers with, rather than the API, which is rate limited to 60 requests an hour without a token — an install script cannot assume a token.

variables

variable
CERTREADER_VERSION a tag to install. Default: latest
CERTREADER_INSTALL_DIR where to put the binary. Default: /usr/local/bin
GITHUB_URL a mirror or enterprise host

sudo is used only if the install directory is not already writable; not having it is an error that says which variable to set.

testing

Debian containers on amd64 and arm64:

case result
linux/amd64, linux/arm64 installs, runs, reads the system trust store
checksum certreader_0.25.1_linux_amd64.tar.gz: OK
tampered archive, served via GITHUB_URL refused, exit 1, nothing installed
CERTREADER_VERSION=v0.25.0 installs 0.25.0
version that does not exist one sentence, not a curl dump
non-root without sudo says which variable to set
darwin installs, notes brew is the supported route

The documented one-liner resolves only once this is on main.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WcPAJjNzG6bqy2FKqKKY1v

There was no way to install on linux short of finding the right archive
on the releases page, unpacking it and moving the binary somewhere. The
script works out the latest release, downloads the archive for the
machine it runs on, and installs it.

It checks the download against the sums published beside it, which
ipscout's equivalent does not, and stops without installing anything if
they disagree. That is the one thing a script piped into a shell should
not skip.

The version is resolved by following the redirect that /releases/latest
answers with, rather than by asking the api, which is rate limited to
sixty requests an hour for anyone not sending a token. An install script
cannot assume a token.

Three variables: CERTREADER_VERSION to pin a tag, CERTREADER_INSTALL_DIR
to put it somewhere else, GITHUB_URL for a mirror. sudo is used only if
the install directory is not already writable, and not having it is an
error that says what to do rather than a permission denied.

Deliberately not a copy of ipscout's script, though it keeps its shape.
That one tests uname against "darwin" where uname says "Darwin", so
under set -e the failed test ends the script before it installs
anything; it also unpacks into whatever directory it was run from and
leaves the binary there.

Tested in debian containers on amd64 and arm64: installs, runs, reads
the system trust store. A tampered archive, served through GITHUB_URL to
a local http server, is refused and nothing is installed. Pinning an old
tag gets that tag, a version that does not exist fails with a sentence
rather than a curl dump, and a non-root user without sudo is told which
variable to set.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WcPAJjNzG6bqy2FKqKKY1v
Copilot AI lite review requested due to automatic review settings September 5, 2026 00:51
@jonhadfield
jonhadfield merged commit 8d61555 into main Sep 5, 2026
3 checks passed
@jonhadfield
jonhadfield deleted the feature/linux-install-script branch September 5, 2026 00:54

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The installer currently allows checksum verification to be skipped and has a couple of correctness/robustness issues that should be addressed before recommending curl | sh.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds a one-line Linux install path for certreader by introducing a standalone install script that downloads the correct release artifact for the current OS/arch and installs it into a standard bin directory, and documents the workflow in the README.

Changes:

  • Document a Linux one-liner install flow and supported environment variables in README.md.
  • Add an install script that resolves the latest release tag, downloads the appropriate tarball + checksums, verifies, and installs to /usr/local/bin (or a configurable directory).
File summaries
File Description
README.md Adds Linux installation instructions, variables, and usage examples for the new installer script.
install New POSIX sh installer that resolves release version, downloads artifacts, verifies checksums, and installs the binary.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 5
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread install
Comment on lines +54 to +57
else
echo "neither sha256sum nor shasum found, skipping checksum" >&2
return 0
fi
Comment thread install
Comment on lines +96 to +99
# the sums file names every archive of that platform, and -c fails on a line it
# has no file for, so check the one that was downloaded
(cd "${work}" && grep " ${archive}\$" "${sums}" > wanted && checksum wanted) ||
fail "${archive} does not match its published checksum"
Comment thread install
Comment on lines +101 to +112
echo "[3/4] Install ${repo} to ${install_dir}"
tar -xzf "${work}/${archive}" -C "${work}" "${repo}" || fail "could not extract ${repo}"
if [ -w "${install_dir}" ]; then
install -m 0755 "${work}/${repo}" "${install_dir}/${repo}" ||
fail "could not write ${install_dir}/${repo}"
elif command -v sudo >/dev/null 2>&1; then
echo "${install_dir} is not writable, using sudo"
sudo install -m 0755 "${work}/${repo}" "${install_dir}/${repo}" ||
fail "could not write ${install_dir}/${repo} with sudo"
else
fail "${install_dir} is not writable and sudo is not available; set CERTREADER_INSTALL_DIR to somewhere you can write"
fi
Comment thread install
@@ -0,0 +1,124 @@
#!/bin/sh
# Install certreader from its github releases.
Comment thread install
[ -n "${arch}" ] || fail "no build for $(uname -m); see ${github_url}/${owner}/${repo}/releases"

if [ "${os}" = "darwin" ]; then
echo "note: on macos, brew install ${owner}/${repo}/${repo} is the supported route" >&2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants