Uses rc suffix so docs system correctly identifies 0.9.x as pre-release.
Remove the rc suffix when ready to declare 0.9.x stable.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dead functions: extract_step, run_hooks, is_parser_plugin,
get_all_plugin_icons, discover_plugin_templates, find_binary_for_cmd,
create_model_record, get_parser_plugins
Dead imports: re, signal, subprocess, django.utils.timezone
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
## Summary
This PR adds automated build and release workflows for Debian (.deb) and
Homebrew packages, replacing the legacy PPA-based distribution model. It
includes build scripts, packaging configurations, and updated GitHub
Actions workflows to generate and publish packages on release.
## Related issues
Improves package distribution and installation experience for Linux and
macOS users.
## Changes these areas
- [x] Internal architecture
- [x] Feature behavior (installation methods)
## Details
### New Build Infrastructure
**Debian Packages:**
- Added `bin/build_deb.sh` - Builds .deb packages using nfpm with
support for multiple architectures (amd64, arm64)
- Added `pkg/debian/nfpm.yaml` - nfpm configuration defining package
metadata, dependencies, and contents
- Added `pkg/debian/archivebox` - Wrapper script that activates the
virtualenv and runs archivebox CLI
- Added `pkg/debian/install.sh` - Post-install setup script that creates
virtualenv and installs dependencies
- Added `pkg/debian/archivebox.service` - Systemd service file for
running archivebox as a service
- Added `pkg/debian/scripts/postinstall.sh` and `preremove.sh` - Package
lifecycle scripts
- Added `bin/release_deb.sh` - Uploads built .deb packages to GitHub
Releases
**Homebrew Packages:**
- Added `bin/build_brew.sh` - Generates Homebrew formula using
homebrew-pypi-poet, auto-populating dependencies and checksums
- Added `brew_dist/archivebox.rb` - Homebrew formula template with
virtualenv support and service definition
- Added `bin/release_brew.sh` - Pushes updated formula to the
homebrew-archivebox tap repository
### Updated Workflows
**`.github/workflows/debian.yml`:**
- Changed trigger from `push` to `release: [published]` for
release-based builds
- Updated to Ubuntu 24.04 and added multi-architecture build matrix
(amd64, arm64)
- Replaced legacy stdeb-based build with nfpm
- Added artifact upload and GitHub Release integration
- Added test job that installs and verifies the .deb package
**`.github/workflows/homebrew.yml`:**
- Changed trigger from `push` to `release: [published]`
- Replaced bottle building with formula generation using
homebrew-pypi-poet
- Added artifact upload and automatic push to homebrew-archivebox tap
- Added test job that installs and verifies the formula
### Updated Installation Instructions
- Modified `bin/setup.sh` to download and install from GitHub Releases
.deb instead of PPA
- Updated `README.md` to document the new .deb installation method
- Updated `bin/build.sh` and `bin/release.sh` to include new build and
release scripts
## Test Plan
- GitHub Actions workflows will test package builds on release events
- Debian workflow includes automated test job that installs the .deb and
verifies `archivebox version`
- Homebrew workflow includes automated test job that installs the
formula and verifies the CLI
- Manual testing can verify installation via: `sudo apt install
./dist/archivebox*.deb` or `brew install archivebox` (after tap setup)
https://claude.ai/code/session_01Vx1EsNrNySgsc8Y67dGzCn
<!-- devin-review-badge-begin -->
---
<a href="https://app.devin.ai/review/archivebox/archivebox/pull/1771"
target="_blank">
<picture>
<source media="(prefers-color-scheme: dark)"
srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1">
<img
src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1"
alt="Open with Devin">
</picture>
</a>
<!-- devin-review-badge-end -->
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Adds automated Debian (.deb) and Homebrew packaging with CI + release
orchestration, replacing the PPA and making installs via `apt` and
`brew` straightforward on Linux and macOS. Packages are thin wrappers
around pip to reduce dependencies; also fixes Docker release tags when
run via the orchestrator.
- **New Features**
- Debian `.deb` via `nfpm` (amd64/arm64): venv at
`/opt/archivebox/venv`, `/usr/bin/archivebox` wrapper (exports PATH)
used by the `systemd` service (no `--setup`); postinstall creates the
`archivebox` user, pins to the package version, enforces Python ≥ 3.13
in `install.sh`, and restarts the service after upgrades. Package
depends only on `python3`/`pip`/`venv`, recommends `git`/`curl`/`wget`.
CI pre-seeds the venv with a local wheel, runs init/status/add on native
`amd64`/`arm64`, and uploads to Releases only after tests pass; release
upload now fails loudly if the Release is missing when triggered by a
release event (skips gracefully on manual runs). `preremove.sh` stops
the service during upgrades to avoid stale venv binaries, and only
disables/removes the venv on full removal.
- Homebrew formula auto-generated with `homebrew-pypi-poet`: virtualenv
install with a single dependency on `python@3.13`, a `post_install` that
initializes in `var/archivebox` with `DATA_DIR` set, and a `caveats`
message showing the data directory. CI generates from a local sdist on
push and from PyPI on release, tests on macOS and Linuxbrew, then pushes
to the `homebrew-archivebox` tap.
- GitHub Actions: `release.yml` orchestrates `pip` → `.deb`/brew →
docker; Docker workflow treats `workflow_call` as a release so
semver/latest tags are published. Tests hardened (e.g., `tests/out`),
README `.deb` install detects arch via `dpkg` and fetches the latest
version via the GitHub API.
- **Migration**
- Ubuntu/Debian: install from Releases (`sudo apt install
/tmp/archivebox.deb`), replacing the PPA.
- macOS/Linuxbrew: `brew tap archivebox/archivebox && brew install
archivebox`.
<sup>Written for commit 36b4055304.
Summary will update on new commits.</sup>
<!-- End of auto-generated description by cubic. -->
The post_install initializes var/archivebox as the data directory,
but users need to know where it is for subsequent commands. The
caveats block is shown after brew install/upgrade to guide users.
https://claude.ai/code/session_01Vx1EsNrNySgsc8Y67dGzCn
preremove.sh stops the service during upgrades (to avoid stale venv
binaries), but postinstall.sh wasn't restarting it. Now postinstall
checks if the service was enabled and restarts it after the venv is
rebuilt, so upgrades don't leave a previously running service down.
https://claude.ai/code/session_01Vx1EsNrNySgsc8Y67dGzCn
- preremove.sh: Stop the systemd service during upgrades (not just
remove/purge) so the running process doesn't use stale venv binaries
while postinstall replaces them. Only disable + remove venv on full
removal.
- debian.yml: Fail loudly when release lookup fails during a release
event (exit 1), but still skip gracefully for workflow_dispatch
manual testing (exit 0). Prevents silently broken .deb publication.
- archivebox.rb + build_brew.sh + homebrew.yml: Add post_install that
initializes ArchiveBox in var/archivebox with DATA_DIR set, using
correct Homebrew system() syntax (no env hash as first arg).
https://claude.ai/code/session_01Vx1EsNrNySgsc8Y67dGzCn
docker.yml uses github.event_name to decide between full release tags
(semver, latest) vs CI-only tags (branch, sha). When release.yml calls
it via `uses:`, the child sees event_name='workflow_call' which was
hitting the non-release path. Now workflow_call is treated the same as
workflow_dispatch so published releases get proper Docker tags.
https://claude.ai/code/session_01Vx1EsNrNySgsc8Y67dGzCn
- install.sh: Replace awk float comparison with integer major/minor check
so Python 3.9 is correctly rejected as < 3.13
- nfpm.yaml: Add git/curl/wget as recommends so users have basic archiving
tools out of the box without needing `archivebox install`
- debian.yml: Restore git/curl/wget in CI smoke test to match what the
package recommends, instead of relying on runner preinstalls
- debian.yml: Guard release upload to skip gracefully when no GitHub
Release exists (fixes workflow_dispatch failures)
https://claude.ai/code/session_01Vx1EsNrNySgsc8Y67dGzCn
The release job was duplicating ~70 lines of PyPI fetching + formula
generation that build_brew.sh already handles. Now it just calls
./bin/build_brew.sh. Also merged the two Linux-only brew setup steps.
https://claude.ai/code/session_01Vx1EsNrNySgsc8Y67dGzCn
Remove all non-essential dependencies from both package formats.
The .deb now only depends on python3, pip, and venv. The brew
formula only depends on python@3.13. All other runtime deps
(node, chrome, yt-dlp, wget, ripgrep, etc.) are installed
on-demand by `archivebox install` at runtime.
Removed from brew formula:
- 6 depends_on entries (node, git, wget, curl, ripgrep, yt-dlp)
- on_linux block (pkg-config, openssl, libffi)
- post_install hook (was running archivebox install)
- service block (users run archivebox server directly)
Removed from .deb:
- 6 depends entries (nodejs, npm, git, wget, curl, ripgrep)
- recommends section (yt-dlp, ffmpeg, chromium)
Net: -126 lines across packaging files.
https://claude.ai/code/session_01Vx1EsNrNySgsc8Y67dGzCn
- systemd service: use /usr/bin/archivebox wrapper (exports venv PATH
for bundled tools like yt-dlp) instead of direct venv binary
- install.sh: prefer python3.13, fail early with clear error if < 3.13,
add comment clarifying the manual (unpinned) fallback behavior
- debian.yml release job: fall back to pyproject.toml version when
github.event.release.tag_name is empty (workflow_dispatch path)
- nfpm.yaml: clarify that install.sh enforces the real >= 3.13 constraint
- CI pre-seed step: expanded comment explaining why we pre-seed with
python3.13 and how it relates to real installs
https://claude.ai/code/session_01Vx1EsNrNySgsc8Y67dGzCn
- Pin cache-apt-pkgs-action to commit SHA for supply-chain safety
- Fix Homebrew post_install to use with_env block instead of env hash
in system() call (idiomatic Homebrew pattern)
- Add clarifying comments to service file, preremove.sh, and nfpm.yaml
explaining user/group creation, directory ownership, and upgrade handling
https://claude.ai/code/session_01Vx1EsNrNySgsc8Y67dGzCn