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
7 changes: 4 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ go vet ./...
go test ./...
```

Those three, plus a cross-compile for five platforms, a `dash -n` pass over the
shell that ships inside the image, and an end-to-end job that starts real
routers on three release/distro combinations, run in CI on every pull request.
Those three, plus a cross-compile for six platforms, a `dash -n` pass over the
shell that ships inside the image and in `tools/`, `sh tools/pins.sh check` over
the copies of the release pin, and an end-to-end job that starts real routers on
three release/distro combinations, run in CI on every pull request.
If a change touches how a router is built or reached, the end-to-end job is the
one that will tell you.

Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ version: 1

routers:
- id: owrt2512
release: "25.12.4"
release: "25.12.5"
```

```console
Expand All @@ -60,7 +60,7 @@ Open the URL. Log in as `root`, leave the password blank.
```yaml
routers:
- id: owrt2512
release: "25.12.4"
release: "25.12.5"
- id: owrt2410
release: "24.10.8"
- id: imm2512
Expand Down Expand Up @@ -96,7 +96,7 @@ $ owlab install owrt2512 luci-app-ttyd

That one is gone after `owlab up --rebuild`. `packages:` survives.

## Install a package that is not in any feed
### Install a package that is not in any feed

Your own, or anything from GitHub Releases. Both URLs, because apk and opkg
name their files differently:
Expand Down Expand Up @@ -177,7 +177,7 @@ apps to check the cascade against.
routers:
- id: real
fidelity: vm
release: "25.12.4"
release: "25.12.5"
packages: ["+kmod-nft-tproxy"]
```

Expand Down Expand Up @@ -249,7 +249,7 @@ output for one release.
- uses: owfeed/owlab/action@v0.6.0
with:
releases: "25.12.5 24.10.8"
install: dist/*/luci-app-mine-*.apk
install: dist/*/luci-app-mine-*
assert: |
http 200 /cgi-bin/luci/admin/services/mine
service mined
Expand All @@ -264,7 +264,7 @@ The same thing locally, and what the action runs:

```console
$ owlab test --release 25.12.5 --release 24.10.8 \
--install 'dist/*/luci-app-mine-*.apk' \
--install 'dist/*/luci-app-mine-*' \
--assert 'http 200 /cgi-bin/luci/admin/services/mine'
```

Expand Down
4 changes: 2 additions & 2 deletions README_ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ dist/
- uses: owfeed/owlab/action@v0.6.0
with:
releases: "25.12.5 24.10.8"
install: dist/*/luci-app-mine-*.apk
install: dist/*/luci-app-mine-*
assert: |
http 200 /cgi-bin/luci/admin/services/mine
service mined
Expand All @@ -265,7 +265,7 @@ summary написано, какой роутер и какая проверка

```console
$ owlab test --release 25.12.5 --release 24.10.8 \
--install 'dist/*/luci-app-mine-*.apk' \
--install 'dist/*/luci-app-mine-*' \
--assert 'http 200 /cgi-bin/luci/admin/services/mine'
```

Expand Down
7 changes: 6 additions & 1 deletion action/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,16 @@ inputs:
install:
description: >-
Packages to install, one per line. A path (globs allowed, e.g.
dist/*/luci-app-mine-*.apk) is copied to the router and installed from
dist/*/luci-app-mine-*) is copied to the router and installed from
there; anything else is looked up in the router's feeds. `owlab build`
writes into a directory named for the architecture, so a pattern needs
that component -- one `*`, not two: these are Go path globs, and `**`
matches nothing.

Each router is given only the format its package manager reads -- .apk on
25.12+, .ipk on 24.10 and earlier -- so one glob covers both release
lines. A pattern ending in .apk leaves the 24.10 router with nothing to
install.
required: false
default: ""
feed:
Expand Down
7 changes: 5 additions & 2 deletions docs/STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*owlab is the bottom of a three-tool stack —
[ECOSYSTEM.md](https://github.com/owfeed/owfeed/blob/main/docs/ECOSYSTEM.md) in
owfeed says where the boundaries run and why. This file says how much of owlab's
side of that exists, as of 2026-07-29.*
side of that exists, as of 2026-09-04.*

It lives here rather than in the shared document on purpose. The shared version
went stale twice, both times on an owlab fact, because nothing in owfeed's CI ever
Expand All @@ -19,7 +19,10 @@ somebody has to edit in the same pull request that made it untrue.
| `owlab build` writes `dist/<arch>/` | The layout `owfeed` and a feed's ingest both read. Built luci-theme-footstrap through the SDK and released it from that tree without rearranging anything |
| Install from a signed feed by name | `owlab test --feed` on 25.12: the package installs out of a signed index and its LuCI page renders. With the key removed the router reports it as not existing at all |
| `owlab releases` without a project | Asking a download server what it publishes needs neither an `owlab.yaml` nor a container engine, and no longer demands either |
| The unit tests pass on Linux, macOS and Windows | `ci.yml` runs `go test`, `owlab doctor` and `owlab version` on `ubuntu-24.04`, `macos-15` and `windows-2025`. Until this was added, "runs everywhere" rested on a cross-compile, and two Windows bugs were living in the gap — permissions derived from a filesystem that has none, and `project.build` run by a shell that is not there |
| `--install` gives each router only its own format | `pkgmgr.FilterFiles` splits by extension before the push, so one glob over `dist/` covers both release lines; what a router did not get is named on its install line, and a router left with nothing is reported as a skip rather than a green install |
| A router built without an `extra_packages` file says so | The image records the failures in `/etc/owlab/extras-failed`; `owlab up` prints them after its table and exits non-zero, `owlab test` fails that router on an `extra_packages` step |
| The release pins cannot go stale unnoticed | `sh tools/pins.sh check` in `ci.yml` fails a release literal in `images/Dockerfile` or a workflow that `images/owlab.yaml` does not pin; `pins.yml` proposes the bump as a pull request |
| The unit tests pass on Linux, macOS and Windows | `ci.yml` runs `go test` on `ubuntu-24.04`, `macos-15` and `windows-2025`, and `owlab doctor` and `owlab version` on the bare macOS and Windows runners. Until this was added, "runs everywhere" rested on a cross-compile, and two Windows bugs were living in the gap — permissions derived from a filesystem that has none, and `project.build` run by a shell that is not there |

## Working, and verified on one platform

Expand Down
2 changes: 1 addition & 1 deletion docs/internals.md
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ reproducible than naming a model.
Upstream combined disk images — kernel, bootloader and rootfs in one file:

```
openwrt-25.12.4-armsr-armv8-generic-squashfs-combined-efi.img.gz
openwrt-25.12.5-armsr-armv8-generic-squashfs-combined-efi.img.gz
```

**squashfs, not ext4.** squashfs is what a router runs: a read-only `/rom` with
Expand Down
20 changes: 10 additions & 10 deletions docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ defaults: # merged into every router
routers:
- id: owrt2512
distro: openwrt # openwrt | immortalwrt
release: "25.12.4"
release: "25.12.5"
packages: ["+luci-app-sqm"] # + adds to defaults, - removes
ports: { http: 8025, ssh: 2225 }

- id: real # fidelity vm only:
fidelity: vm
release: "25.12.4"
release: "25.12.5"
memory: 512M # qemu -m
cpus: 2 # qemu -smp
disk: 2G # extroot disk; 0 to use the image's own
Expand Down Expand Up @@ -253,8 +253,8 @@ carries no traffic.

### Pin point releases

`release: "25.12.4"`, not `"25.12"`. The package manager records hard version
pins (`base-files=1707~4ccb782af7` in `/etc/apk/world`), so a 25.12.1 rootfs
`release: "25.12.5"`, not `"25.12"`. The package manager records hard version
pins (`base-files=1707~4ccb782af7` in `/etc/apk/world`), so a 25.12.4 rootfs
pointed at the 25.12.5 feed fails every install with `breaks: world[...]`.
owlab pins the feed to the exact release the rootfs came from, and old
point releases stay available upstream, so this always works.
Expand All @@ -271,9 +271,9 @@ installing the LuCI set. Starting from a published image takes seconds:
```yaml
routers:
- id: owrt2512
release: "25.12.4"
release: "25.12.5"
arch: x86_64
image: ghcr.io/owfeed/owlab-rootfs:openwrt-25.12.4-x86_64
image: ghcr.io/owfeed/owlab-rootfs:openwrt-25.12.5-x86_64
```

Everything else still applies on top — your `packages:` are installed (the
Expand All @@ -284,8 +284,8 @@ different code path, so nothing behaves differently from a locally built one.
Published tags are `<distro>-<release>-<arch>`:

```
ghcr.io/owfeed/owlab-rootfs:openwrt-25.12.4-x86_64
ghcr.io/owfeed/owlab-rootfs:openwrt-25.12.4-aarch64_generic
ghcr.io/owfeed/owlab-rootfs:openwrt-25.12.5-x86_64
ghcr.io/owfeed/owlab-rootfs:openwrt-25.12.5-aarch64_generic
ghcr.io/owfeed/owlab-rootfs:openwrt-24.10.8-x86_64
ghcr.io/owfeed/owlab-rootfs:immortalwrt-25.12.1-x86_64
...
Expand Down Expand Up @@ -346,7 +346,7 @@ running router, tear everything down, exit 0 or 1.

```console
$ owlab test --release 25.12.5 --release 24.10.8 \
--install 'dist/*/luci-app-mine-*.apk' \
--install 'dist/*/luci-app-mine-*' \
--assert 'http 200 /cgi-bin/luci/admin/services/mine'
```

Expand Down Expand Up @@ -469,7 +469,7 @@ add'` is the whole of "is anything stale".
- uses: owfeed/owlab/action@v0.6.0
with:
releases: "25.12.5 24.10.8"
install: dist/*/luci-app-mine-*.apk
install: dist/*/luci-app-mine-*
assert: |
http 200 /cgi-bin/luci/admin/services/mine
service mined
Expand Down
4 changes: 2 additions & 2 deletions docs/reference_ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ owlab не может определить сам: установка в нео

```console
$ owlab test --release 25.12.5 --release 24.10.8 \
--install 'dist/*/luci-app-mine-*.apk' \
--install 'dist/*/luci-app-mine-*' \
--assert 'http 200 /cgi-bin/luci/admin/services/mine'
```

Expand Down Expand Up @@ -410,7 +410,7 @@ caught», lua-шный `stack traceback:`): поймав исключение, L
- uses: owfeed/owlab/action@v0.6.0
with:
releases: "25.12.5 24.10.8"
install: dist/*/luci-app-mine-*.apk
install: dist/*/luci-app-mine-*
assert: |
http 200 /cgi-bin/luci/admin/services/mine
service mined
Expand Down
7 changes: 7 additions & 0 deletions docs/releasing.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ anyone editing a version number, and 25.12.4 stays available for whoever has
not moved yet. `keep` defaults to 2 and is an input on both the manual and the
called runs.

Moving the pin itself is not a one-line edit: the same release number is copied
into `images/Dockerfile` and the CI workflows, and `ci.yml` fails a copy that
names a release `images/owlab.yaml` does not pin. Use `sh tools/pins.sh bump
<old> <new>`, which moves every copy at once. `pins.yml` proposes that bump as
a pull request daily. Both are in the
[runbook](runbook.md#check-the-copies-of-the-pin).

Two things the resolver checks that a listing alone does not tell you:

- **The release actually has artifacts for the target.** A point release
Expand Down
7 changes: 7 additions & 0 deletions docs/releasing_ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,13 @@ GOARCH-соответствия. Manifest list такую матрицу не в
тех, кто ещё не переехал. `keep` по умолчанию 2 и является входом и для ручного
запуска, и для вызова из релиза.

Сдвинуть сам пин одной правкой нельзя: тот же номер релиза скопирован в
`images/Dockerfile` и в CI-воркфлоу, а `ci.yml` роняет копию, которая называет
релиз, отсутствующий среди пинов `images/owlab.yaml`. Используйте `sh
tools/pins.sh bump <старый> <новый>` — он двигает все копии сразу. `pins.yml`
предлагает этот сдвиг пулл-реквестом ежедневно. Оба описаны в
[ранбуке](runbook_ru.md#проверить-копии-пина).

Две вещи, которые резолвер проверяет и о которых листинг не говорит:

- **У релиза действительно есть артефакты для таргета.** Точечный релиз
Expand Down
10 changes: 7 additions & 3 deletions docs/runbook.md
Original file line number Diff line number Diff line change
Expand Up @@ -328,9 +328,13 @@ defaults:
$ owlab up --rebuild
```

Verify: the build prints `owlab: installing luci-app-mine-1.0-r1.apk`. A
failure here is fatal — the build stops rather than handing you a router
quietly missing it.
Verify: the build prints `owlab: installing luci-app-mine-1.0-r1.apk`.

If it cannot be installed, the build carries on and that router starts without
it, so one bad file does not cancel the other routers. `owlab up` names what is
missing after its table and exits non-zero, `owlab test` fails that router on
its `extra_packages` step, and the list stays on the router in
`/etc/owlab/extras-failed`.

Both URLs, because apk and opkg do not share a naming scheme. Pin an exact
release, never a `latest` link: these are installed without checking
Expand Down
10 changes: 7 additions & 3 deletions docs/runbook_ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -328,9 +328,13 @@ defaults:
$ owlab up --rebuild
```

Проверка: сборка печатает `owlab: installing luci-app-mine-1.0-r1.apk`. Провал
здесь фатален — сборка останавливается, а не отдаёт вам роутер, тихо лишённый
этого пакета.
Проверка: сборка печатает `owlab: installing luci-app-mine-1.0-r1.apk`.

Если пакет поставить не удалось, сборка продолжается и этот роутер стартует без
него — один плохой файл не отменяет остальные роутеры. `owlab up` называет
недостающее после своей таблицы и завершается с ненулевым кодом, `owlab test`
роняет этот роутер на шаге `extra_packages`, а список остаётся на роутере в
`/etc/owlab/extras-failed`.

Оба URL, потому что apk и opkg не делят схему именования. Пиньте точный релиз,
а не ссылку на `latest`: подписи здесь не проверяются.
Expand Down
2 changes: 1 addition & 1 deletion examples/luci-theme/owlab.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ defaults:

routers:
- id: owrt2512
release: "25.12.4"
release: "25.12.5"
ports: { http: 8025, ssh: 2225 }

- id: owrt2410
Expand Down
2 changes: 1 addition & 1 deletion examples/workflow/package-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
strategy:
fail-fast: false
matrix:
release: ["25.12.4", "24.10.8"]
release: ["25.12.5", "24.10.8"]
steps:
- uses: actions/checkout@v5

Expand Down