Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,40 @@ jobs:
echo "CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=${TOOLCHAIN}/bin/aarch64-linux-android24-clang" >> "$GITHUB_ENV"
- run: cargo check --target aarch64-linux-android

deb:
# The Debian package on the release's build image (ADR 0034): a debug
# build is enough to check the package's layout, its Depends and the
# oldest glibc it declares, by installing it with apt.
name: Debian package (${{ matrix.arch }})
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
include:
- arch: amd64
os: ubuntu-22.04
- arch: arm64
os: ubuntu-22.04-arm
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install build deps
run: sudo apt-get update && sudo apt-get install -y libwayland-dev apt-utils
- name: Install Rust
run: |
rustup toolchain install stable --profile minimal
rustup default stable
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
- run: cargo build --locked
- name: Build the package and install it with apt
run: |
set -euo pipefail
version="$(sed -n 's/^version = "\(.*\)"$/\1/p' Cargo.toml | head -n 1)"
sh packaging/apt/build-deb.sh target/debug/gitreant "$version" ${{ matrix.arch }} deb
sh packaging/apt/install-test.sh deb "$version" ${{ matrix.arch }}

web:
name: Frontend + Storybook
runs-on: ubuntu-latest
Expand Down Expand Up @@ -181,6 +215,7 @@ jobs:
with:
persist-credentials: false
- run: bash .github/scripts/test-release-scripts.sh
- run: bash packaging/apt/test-build-deb.sh
- name: The released version has notes in CHANGELOG.md
run: >
bash .github/scripts/release-notes.sh
Expand Down
62 changes: 58 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ jobs:
# Desktop targets build natively (GitHub has free arm64 runners for
# public repositories, so no cross toolchains for rfd's GUI libraries);
# Android (Termux) is the one cross build, linked with the NDK's clang —
# rfd/open are cfg'd out there.
# rfd/open are cfg'd out there. Linux builds on Ubuntu 22.04, whose
# glibc sets the oldest glibc the executable starts on (ADR 0034).
name: Build (${{ matrix.target }})
needs: [version, test]
runs-on: ${{ matrix.os }}
Expand All @@ -86,10 +87,10 @@ jobs:
os: windows-11-arm
archive: zip
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
os: ubuntu-22.04
archive: tar.gz
- target: aarch64-unknown-linux-gnu
os: ubuntu-24.04-arm
os: ubuntu-22.04-arm
archive: tar.gz
- target: x86_64-apple-darwin
os: macos-26
Expand Down Expand Up @@ -168,9 +169,51 @@ jobs:
name: gitreant-${{ matrix.target }}
path: gitreant-${{ matrix.target }}.*

deb:
# The Debian packages (ADR 0034), built from the release executables and
# installed with apt in Debian and Ubuntu containers before anything is
# published. A prerelease tag rehearses this job too, with a package
# version that sorts before the release (0.3.0~rc.1); the package
# registry indexes stable releases only.
name: Debian package (${{ matrix.arch }})
needs: build
runs-on: ${{ matrix.os }}
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
include:
- arch: amd64
target: x86_64-unknown-linux-gnu
os: ubuntu-latest
- arch: arm64
target: aarch64-unknown-linux-gnu
os: ubuntu-24.04-arm
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: gitreant-${{ matrix.target }}
path: artifacts
- name: Build the package and install it with apt
run: |
set -euo pipefail
sudo apt-get update -qq && sudo apt-get install -y -qq apt-utils
version="$(sed -n 's/^version = "\(.*\)"$/\1/p' Cargo.toml | head -n 1)"
deb_version="$(sh packaging/apt/deb-version.sh "$version" "$GITHUB_REF_NAME")"
tar xzf artifacts/gitreant-${{ matrix.target }}.tar.gz -C artifacts
sh packaging/apt/build-deb.sh artifacts/gitreant "$deb_version" ${{ matrix.arch }} deb
sh packaging/apt/install-test.sh deb "$version" ${{ matrix.arch }}
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: gitreant-deb-${{ matrix.arch }}
path: deb/*.deb

release:
name: Create Release
needs: build
needs: [build, deb]
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
Expand All @@ -188,6 +231,17 @@ jobs:
path: artifacts
merge-multiple: true

- name: Write SHA256SUMS
# The package registry checks every package against it before
# indexing (ADR 0034), and anyone can check a download the same way.
# Written outside the directory so it does not list itself.
working-directory: artifacts
run: |
set -euo pipefail
find . -maxdepth 1 -type f -printf '%P\n' | LC_ALL=C sort | xargs sha256sum >../SHA256SUMS
mv ../SHA256SUMS .
cat SHA256SUMS

- name: Attest build provenance
# Signed SLSA provenance for every artifact, published before the
# release itself so a failure aborts instead of shipping unattested
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Debian packages for amd64 and arm64, attached to each release and
installable with `apt` from `pkg.shortarrow.jp`, and a `SHA256SUMS` for
every release asset
([ADR 0034](https://github.com/ShortArrow/gitreant/blob/main/docs/adr/0034-debian-packages.md)).

### Fixed

- The arm64 Linux binary starts on glibc 2.35 and later, Debian 12 and
Raspberry Pi OS bookworm included; it needed glibc 2.39.

## [0.2.4] - 2026-10-15

### Added
Expand Down
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,25 @@ Every feature in detail: [docs/FEATURES.md](docs/FEATURES.md).

## Install / Build

Requirements: Rust (stable), Node.js + pnpm.
On Debian 12 or Ubuntu 22.04 and later, amd64 or arm64, from the APT
repository at `pkg.shortarrow.jp`
([ADR 0034](docs/adr/0034-debian-packages.md)):

```console
$ sudo curl -fsSLo /usr/share/keyrings/shortarrow-archive-keyring.gpg https://pkg.shortarrow.jp/apt/shortarrow-archive-keyring.gpg
$ echo "deb [signed-by=/usr/share/keyrings/shortarrow-archive-keyring.gpg] https://pkg.shortarrow.jp/apt stable main" | sudo tee /etc/apt/sources.list.d/shortarrow.list
$ sudo apt update
$ sudo apt install shortarrow-archive-keyring gitreant
```

Installing `shortarrow-archive-keyring` by name keeps it, and the key that
verifies the repository, when gitreant is removed; later keys arrive with
`apt upgrade`. `gitreant --version` checks the install.

Every GitHub Release also carries the binaries for Windows, macOS, Linux
and Termux, with a `SHA256SUMS`.

To build from source, you need Rust (stable), Node.js + pnpm:

```console
$ make build # build the frontend and embed it into a release binary
Expand Down
10 changes: 7 additions & 3 deletions docs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,13 @@ How a release is guarded is [ADR 0030](adr/0030-release-safeguards.md).
1. checks that the tag is on `main`, matches `Cargo.toml` and has a
changelog section;
2. runs `cargo test --locked` on every platform it ships for;
3. builds the native binaries with the frontend embedded, attests them
(SLSA provenance) and attaches them to a GitHub Release whose notes
are the changelog section;
3. builds the native binaries with the frontend embedded, builds the
Debian packages from the Linux ones and installs them with apt in
containers ([ADR 0034](adr/0034-debian-packages.md)), attests them
all (SLSA provenance) and attaches them, with a `SHA256SUMS`, to a
GitHub Release whose notes are the changelog section. The APT
registry ([ShortArrow/pkg](https://github.com/ShortArrow/pkg)) picks
the packages up from there within the hour;
4. waits for approval in the `release` environment, then publishes the
crate to crates.io via OIDC Trusted Publishing. The published package
ships the prebuilt `frontend/dist` (see the `include` list in
Expand Down
29 changes: 29 additions & 0 deletions docs/adr/0034-debian-packages.jp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# ADR 0034: 共有の APT リポジトリ向けに Debian パッケージを配る

## Status

Accepted (2026-10-20)

## Context

Linux のユーザーは gitreant をリリースの tar.gz か `cargo install` で入れ、手で入れ替えるまでその版を使い続ける。`https://pkg.shortarrow.jp/apt` は ShortArrow のツールを配る APT リポジトリである([ShortArrow/pkg ADR 0001](https://github.com/ShortArrow/pkg/blob/main/docs/adr/0001-package-registry.md))。リポジトリ自身はパッケージをビルドしない。各プロジェクトが `.deb` をビルドし、インストールできることを確かめ、`SHA256SUMS` と一緒に自分の GitHub Release に添付する。リポジトリは各パッケージをその `SHA256SUMS` で照合し、置かれた場所のまま索引に載せる。パッケージの中身、名前、`Depends` はプロジェクトが決める。

リポジトリは公開した版ごとに、`debian:bookworm`(glibc 2.36)と `ubuntu:24.04` にインストールして確かめる。0.2.3 までの gitreant は `ubuntu-latest`(24.04、glibc 2.39)でビルドしている。0.2.3 の実行ファイルを `readelf -V` で見ると、x86_64 版は `GLIBC_2.39` を弱い参照でだけ、`GLIBC_2.34` を必須として要求する。一方 aarch64 版は `GLIBC_2.39` を必須として要求する。動的ローダーは、必須として要求された glibc のバージョンが無い実行ファイルを起動しない。そのため arm64 の tar.gz は、Raspberry Pi OS の bookworm も含め、bookworm では起動しない。

## Decision

- **パッケージ。** 名前は `gitreant`、バージョンはリリースの版に Debian リビジョン `1` を付けたもの(`0.3.0-1`)で、`amd64` と `arm64` を作る。`/usr/bin/gitreant` と、`/usr/share/doc/gitreant/` 以下のライセンスを入れる。ビルドは `packaging/apt/build-deb.sh` が行う。
- `Depends`:実行ファイルが名指しするライブラリ(`libc6`、`libgcc-s1`、`libwayland-client0`)、`gitreant doctor` が必須とする `git`、リポジトリの `shortarrow-archive-keyring`。最後の 1 つは、gitreant が入っている間、ソースを検証する鍵を残しておくためのもの。
- `libc6` の下限は、実行ファイルが必須として要求する glibc のバージョンのうち最も高いもの。手で書かず、ビルド時に `readelf` で読み取る(`packaging/apt/glibc-floor.sh`)。
- `Recommends: xdg-utils`(ブラウザを開く)。`Suggests: gh, gnupg`(`gitreant doctor` が任意とするツール)。
- プレリリースのタグでは、接尾辞を `~` の後ろに付けた版でパッケージを作る(`v0.3.0-rc.1` なら `0.3.0~rc.1-1`。`packaging/apt/deb-version.sh` が決める)。`-` を使うと Debian の順序で正式版より後ろに並ぶ。`Cargo.toml` の版だけを使うと、rc と正式版が中身の違う同じ版になり、rc を入れたマシンを apt が正式版に上げない。`Cargo.toml` と違う版を名指すタグにはパッケージを作らない。
- **Linux 版のリリース用実行ファイルは `ubuntu-22.04` と `ubuntu-22.04-arm`(glibc 2.35)でビルドする。** これでどちらも bookworm より新しい glibc を要求しない。
- **リリースのワークフロー**は、リリース用の実行ファイルからパッケージをビルドする。それぞれを使い捨ての署名付きリポジトリから `debian:bookworm`、`ubuntu:22.04`、`ubuntu:24.04` に `apt` でインストールし、`gitreant --version` と `gitreant doctor` を実行する(`packaging/apt/install-test.sh`)。パッケージは、全アセットを載せた `SHA256SUMS` と一緒に GitHub Release に添付する。CI もプルリクエストごとに、同じイメージ上のデバッグビルドで同じことを行う。

## Consequences

- リポジトリが gitreant を載せれば、安定版のリリースは `apt upgrade` で Debian と Ubuntu に届く。載るまでの間や、リポジトリの反映が遅れたときも、パッケージは GitHub Release にある。
- Release のページからダウンロードした `.deb` は、単独ではインストールできない。`shortarrow-archive-keyring` はリポジトリにしか無いため。
- arm64 の tar.gz は、bookworm を含む glibc 2.35 以降で起動する。
- GitHub はいずれ Ubuntu 22.04 のイメージを廃止する。新しいイメージでビルドすると、誰も選ばないまま `libc6` の下限が上がりうる。そのときは bookworm でのインストールテストが失敗するので、ビルドを bookworm のコンテナに移す。
- GitHub Release には毎回 `SHA256SUMS` が付く。
72 changes: 72 additions & 0 deletions docs/adr/0034-debian-packages.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# ADR 0034: Ship Debian packages for the shared APT registry

## Status

Accepted (2026-10-20)

## Context

A Linux user installs gitreant from a release tarball or with
`cargo install`, and keeps that version until they replace it by hand.
`https://pkg.shortarrow.jp/apt` is the APT repository for ShortArrow's
tools ([ShortArrow/pkg ADR 0001](https://github.com/ShortArrow/pkg/blob/main/docs/adr/0001-package-registry.md)).
It builds no package itself. Each project builds its `.deb` files, tests
that they install, and attaches them to its GitHub Release with a
`SHA256SUMS` asset; the registry checks each package against that file and
indexes it where it is. What a package contains, its name and its
`Depends` are the project's to decide.

The registry checks every published version by installing it in
`debian:bookworm` (glibc 2.36) and `ubuntu:24.04`. gitreant up to 0.2.3 is
built on `ubuntu-latest` (24.04, glibc 2.39). `readelf -V` on the 0.2.3
executables shows that the x86_64 one needs `GLIBC_2.39` only weakly and
`GLIBC_2.34` outright, while the aarch64 one needs `GLIBC_2.39` outright.
The dynamic loader refuses to start an executable that needs a missing
glibc version outright, so the arm64 tarball does not start on bookworm,
Raspberry Pi OS bookworm included.

## Decision

- **The package.** `gitreant`, versioned as the release with Debian
revision `1` (`0.3.0-1`), for `amd64` and `arm64`. It installs
`/usr/bin/gitreant` and the licences under `/usr/share/doc/gitreant/`.
`packaging/apt/build-deb.sh` builds it.
- `Depends`: the libraries the executable names (`libc6`, `libgcc-s1`,
`libwayland-client0`), `git`, which `gitreant doctor` reports as
required, and the registry's `shortarrow-archive-keyring`, so the key
that verifies the source stays installed while gitreant is.
- The `libc6` floor is the highest glibc version the executable needs
outright, read with `readelf` at build time
(`packaging/apt/glibc-floor.sh`), not written by hand.
- `Recommends: xdg-utils`, which opens the browser; `Suggests: gh,
gnupg`, the tools `gitreant doctor` reports as optional.
- A prerelease tag builds the package with its suffix after a `~`
(`v0.3.0-rc.1` gives `0.3.0~rc.1-1`, by `packaging/apt/deb-version.sh`).
A `-` would sort it after the release in Debian's ordering, and
`Cargo.toml`'s version alone would give an rc and its release the same
version with different contents, so apt would not upgrade a machine
that installed the rc. A tag that names a version other than
`Cargo.toml`'s gets no package.
- **The Linux release executables are built on `ubuntu-22.04` and
`ubuntu-22.04-arm`** (glibc 2.35), so neither needs a glibc newer than
bookworm's.
- **The release workflow** builds the packages from the release
executables, installs each with `apt` from a throwaway signed repository
in `debian:bookworm`, `ubuntu:22.04` and `ubuntu:24.04`, and runs
`gitreant --version` and `gitreant doctor` there
(`packaging/apt/install-test.sh`). It attaches them to the GitHub Release
with a `SHA256SUMS` listing every asset. CI does the same on every pull
request with a debug build on the same images.

## Consequences

- Once the registry lists gitreant, `apt upgrade` delivers each stable
release to Debian and Ubuntu machines. Until then, and whenever the
registry lags, the packages are on the GitHub Release.
- A `.deb` downloaded from the Release page does not install on its own:
`shortarrow-archive-keyring` exists only in the registry.
- The arm64 tarball starts on glibc 2.35 and later, bookworm included.
- GitHub will retire the Ubuntu 22.04 images. A build on a newer image can
raise the `libc6` floor without anyone choosing it; the bookworm install
test then fails, and the build has to move into a bookworm container.
- Every GitHub Release carries a `SHA256SUMS`.
1 change: 1 addition & 0 deletions docs/adr/README.jp.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ gitreant の設計判断の記録。各 ADR は決定時点で凍結され、変
| [0031](0031-wording-only-changes.jp.md) | 片方の言語だけの言い回しの修正はコミットの印で日英同時更新の対象から外す | Accepted |
| [0032](0032-static-crt-on-windows.jp.md) | Windows 版は C ランタイムを静的リンクする | Accepted |
| [0033](0033-diff-attribute.jp.md) | バイナリかどうかは git diff と同じく diff 属性で決める | Accepted |
| [0034](0034-debian-packages.jp.md) | 共有の APT リポジトリ向けに Debian パッケージを配る | Accepted |
1 change: 1 addition & 0 deletions docs/adr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,4 @@ are canonical; the files below are their English translations.
| [0031](0031-wording-only-changes.md) | Exempt a one-language rewording from the bilingual check by a commit mark | Accepted |
| [0032](0032-static-crt-on-windows.md) | Link the C runtime statically on Windows | Accepted |
| [0033](0033-diff-attribute.md) | Decide binary diffs by the diff attribute, as git diff does | Accepted |
| [0034](0034-debian-packages.md) | Ship Debian packages for the shared APT registry | Accepted |
Loading
Loading