Skip to content

Commit 2f75080

Browse files
committed
Add tool.json and generate the README Install section from it
The manifest is what the family website reads to build this tool's card and detail page: tagline, category, screenshots, keys, install channels and the security posture. The Install section of the README is now rendered from the same block by tui-kit/tools/render-install.py, so the repository and the site cannot drift apart on how the tool is installed. The distribution packages are declared with available:false and their real commands, which is how they show as coming soon rather than as nothing. CI validates the manifest against the family schema, and the release job tells the website a release shipped once a SITE_DISPATCH_TOKEN secret exists.
1 parent 71847bc commit 2f75080

4 files changed

Lines changed: 260 additions & 6 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,38 @@ jobs:
6969
GOARCH: ${{ matrix.goarch }}
7070
run: go build -trimpath -o "/tmp/tui-firewall_${GOARCH}" ./cmd/tui-firewall
7171

72+
manifest:
73+
name: validate tool.json
74+
runs-on: ubuntu-latest
75+
steps:
76+
- uses: actions/checkout@v4
77+
78+
- uses: actions/setup-node@v4
79+
with:
80+
node-version: "22"
81+
82+
# The schema is shared by the family and lives in tui-kit, so a tool
83+
# cannot drift from it by editing a local copy.
84+
- name: fetch the manifest schema from tui-kit
85+
run: |
86+
curl -fsSL --retry 3 -o /tmp/tool.schema.json \
87+
https://raw.githubusercontent.com/tui-tools/tui-kit/main/schema/tool.schema.json
88+
89+
- name: validate tool.json
90+
run: |
91+
npx --yes -p ajv-cli@5 -p ajv-formats@3 ajv validate \
92+
--spec=draft2020 -c ajv-formats \
93+
-s /tmp/tool.schema.json -d tool.json
94+
7295
release:
7396
name: release
7497
if: startsWith(github.ref, 'refs/tags/v')
75-
needs: [check, cross-build]
98+
needs: [check, cross-build, manifest]
7699
runs-on: ubuntu-latest
77100
permissions:
78101
contents: write
102+
env:
103+
SITE_DISPATCH_TOKEN: ${{ secrets.SITE_DISPATCH_TOKEN }}
79104
steps:
80105
- uses: actions/checkout@v4
81106
with:
@@ -92,3 +117,16 @@ jobs:
92117
args: release --clean
93118
env:
94119
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
120+
121+
# Tell the family website that a release shipped, so it rebuilds now
122+
# instead of waiting for its hourly run. Inert until the repository
123+
# secret SITE_DISPATCH_TOKEN exists: a fine-grained PAT with
124+
# "Contents: read and write" on tui-tools/tui-tools.github.io.
125+
- name: notify the website
126+
if: env.SITE_DISPATCH_TOKEN != ''
127+
env:
128+
GH_TOKEN: ${{ env.SITE_DISPATCH_TOKEN }}
129+
run: |
130+
gh api repos/tui-tools/tui-tools.github.io/dispatches \
131+
-f event_type=tool-released \
132+
-f 'client_payload[tool]=tui-firewall'

‎Makefile‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LDFLAGS := -s -w -X main.version=$(VERSION)
99
# kit, which is already a dependency: ask the module cache where it landed.
1010
KIT = $(shell $(GO) list -m -f '{{.Dir}}' github.com/tui-tools/tui-kit)
1111

12-
.PHONY: all build test vet fmt fmt-check lint check demo clean tidy install screenshots
12+
.PHONY: manifest readme all build test vet fmt fmt-check lint check demo clean tidy install screenshots
1313

1414
all: check build
1515

@@ -68,6 +68,18 @@ screenshots: build
6868
--screen main= --screen add=a --screen delete=d \
6969
--screen policies=p --screen help=?
7070

71+
## readme: regenerate the Install section of the README from tool.json.
72+
readme:
73+
python3 $(KIT)/tools/render-install.py --manifest tool.json --readme README.md
74+
75+
## manifest: validate tool.json against the family schema in tui-kit.
76+
manifest:
77+
@curl -fsSL --retry 3 -o /tmp/tui-tool.schema.json \
78+
https://raw.githubusercontent.com/tui-tools/tui-kit/main/schema/tool.schema.json
79+
@npx --yes -p ajv-cli@5 -p ajv-formats@3 ajv validate \
80+
--spec=draft2020 -c ajv-formats \
81+
-s /tmp/tui-tool.schema.json -d tool.json
82+
7183
## clean: remove build output.
7284
clean:
7385
rm -rf $(BIN) dist

‎README.md‎

Lines changed: 83 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,95 @@ fills the gap on a server or a tiling desktop, in the
1515
1616
## Install
1717

18-
Grab a static binary from the [releases](https://github.com/tui-tools/tui-firewall/releases),
19-
or build it yourself:
18+
<!-- install:start -->
19+
<!-- Generated by tui-kit/tools/render-install.py from tool.json. -->
20+
<!-- Edit the manifest, then run `make readme`. -->
21+
22+
### Any distribution, static binary
23+
24+
```sh
25+
curl -fsSL https://github.com/tui-tools/tui-firewall/releases/download/v0.1.0/tui-firewall_0.1.0_linux_amd64.tar.gz | tar -xz tui-firewall
26+
sudo install -m0755 tui-firewall /usr/local/bin/tui-firewall
27+
```
28+
29+
One static binary. Verify it against checksums.txt from the same release.
30+
31+
### From source
2032

2133
```sh
2234
git clone https://github.com/tui-tools/tui-firewall
23-
cd tui-firewall
24-
make build
35+
cd tui-firewall && make build
2536
sudo install -m0755 bin/tui-firewall /usr/local/bin/tui-firewall
2637
```
2738

39+
Needs Go 1.26 or newer.
40+
41+
The distribution packages are not published yet. The commands below are here so
42+
you know what they will be; a package repository at `pkgs.tui.tools` is what
43+
turns them on.
44+
45+
### Arch Linux — coming soon
46+
47+
Needs the tui-tools repository, which is a [one-time
48+
setup](https://tui-tools.github.io/install/).
49+
50+
```sh
51+
sudo pacman -S tui-firewall
52+
```
53+
54+
Add the tui-tools repository to pacman.conf first.
55+
56+
### Arch Linux (AUR) — coming soon
57+
58+
```sh
59+
paru -S tui-firewall-bin
60+
```
61+
62+
The -bin package installs the released static binary.
63+
64+
### Debian and Ubuntu — coming soon
65+
66+
Needs the tui-tools repository, which is a [one-time
67+
setup](https://tui-tools.github.io/install/).
68+
69+
```sh
70+
sudo apt install tui-firewall
71+
```
72+
73+
Add the tui-tools apt repository and its keyring first.
74+
75+
### Fedora and RHEL — coming soon
76+
77+
Needs the tui-tools repository, which is a [one-time
78+
setup](https://tui-tools.github.io/install/).
79+
80+
```sh
81+
sudo dnf install tui-firewall
82+
```
83+
84+
Add the tui-tools.repo file first.
85+
86+
### openSUSE — coming soon
87+
88+
Needs the tui-tools repository, which is a [one-time
89+
setup](https://tui-tools.github.io/install/).
90+
91+
```sh
92+
sudo zypper install tui-firewall
93+
```
94+
95+
Add the tui-tools repository first.
96+
97+
### Verify a download
98+
99+
Every release of `tui-firewall` ships a `checksums.txt`. Check an archive
100+
against it before installing:
101+
102+
```sh
103+
sha256sum -c checksums.txt --ignore-missing
104+
```
105+
<!-- install:end -->
106+
28107
One static binary, no daemon, no state of its own. Nothing keeps running after
29108
you quit.
30109

‎tool.json‎

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
{
2+
"schemaVersion": 1,
3+
"name": "tui-firewall",
4+
"binary": "tui-firewall",
5+
"tagline": "The system firewall, with every change previewed before it runs",
6+
"description": "A terminal UI for the Linux firewall. It shows the rules you actually have — action, direction, ports, source, destination, app profile, IPv6 and `route` rules included — alongside the default policies and the logging level.\n\nThe UI never builds a command line. It talks to a backend behind an interface, which returns a firewall-neutral model and produces command values; the confirm dialog shows that value and hands the same one to the runner, so what you read is what executes. `ufw` today, `firewalld` behind the same interface next.\n\nRun `tui-firewall --demo` to drive an in-memory sample firewall: every key works, every command is built and previewed for real, and nothing touches your system.",
7+
"category": "firewall",
8+
"homepage": "https://github.com/tui-tools/tui-firewall",
9+
"repo": "https://github.com/tui-tools/tui-firewall",
10+
"license": "MIT",
11+
"platforms": ["linux/amd64", "linux/arm64"],
12+
"icon": "assets/icon.svg",
13+
"logo": "assets/logo.png",
14+
"screenshots": [
15+
{
16+
"path": "docs/screenshots/tui-firewall-main.png",
17+
"caption": "The rules table, with status, default policies and logging in the header"
18+
},
19+
{
20+
"path": "docs/screenshots/tui-firewall-delete.png",
21+
"caption": "Deleting a rule: the exact ufw command line, shown before it runs"
22+
},
23+
{
24+
"path": "docs/screenshots/tui-firewall-add.png",
25+
"caption": "The add-rule form: action, direction, ports, protocol, source, destination"
26+
},
27+
{
28+
"path": "docs/screenshots/tui-firewall-policies.png",
29+
"caption": "Changing a default policy for incoming, outgoing or routed traffic"
30+
},
31+
{
32+
"path": "docs/screenshots/tui-firewall-help.png",
33+
"caption": "The help screen, generated from the same action table as the key map"
34+
}
35+
],
36+
"keys": [
37+
{ "key": "a", "action": "Add a rule" },
38+
{ "key": "d", "action": "Delete the selected rule" },
39+
{ "key": "e", "action": "Enable or disable the firewall" },
40+
{ "key": "p", "action": "Change a default policy" },
41+
{ "key": "L", "action": "Change the logging level" },
42+
{ "key": "r", "action": "Reload the firewall" },
43+
{ "key": "/", "action": "Filter rules across every column" },
44+
{ "key": "[ / ]", "action": "Previous / next group, on multi-group backends" },
45+
{ "key": "R", "action": "Re-read the firewall" },
46+
{ "key": "?", "action": "Help" },
47+
{ "key": "q", "action": "Quit" }
48+
],
49+
"install": {
50+
"pacman": {
51+
"available": false,
52+
"package": "tui-firewall",
53+
"repo": "tui-tools",
54+
"requires_repo_setup": true,
55+
"command": "sudo pacman -S tui-firewall",
56+
"url": "https://pkgs.tui.tools/arch",
57+
"note": "Add the tui-tools repository to pacman.conf first."
58+
},
59+
"aur": {
60+
"available": false,
61+
"package": "tui-firewall-bin",
62+
"repo": "aur",
63+
"command": "paru -S tui-firewall-bin",
64+
"url": "https://aur.archlinux.org/packages/tui-firewall-bin",
65+
"note": "The -bin package installs the released static binary."
66+
},
67+
"apt": {
68+
"available": false,
69+
"package": "tui-firewall",
70+
"repo": "tui-tools",
71+
"requires_repo_setup": true,
72+
"command": "sudo apt install tui-firewall",
73+
"url": "https://pkgs.tui.tools/deb",
74+
"note": "Add the tui-tools apt repository and its keyring first."
75+
},
76+
"dnf": {
77+
"available": false,
78+
"package": "tui-firewall",
79+
"repo": "tui-tools",
80+
"requires_repo_setup": true,
81+
"command": "sudo dnf install tui-firewall",
82+
"url": "https://pkgs.tui.tools/rpm",
83+
"note": "Add the tui-tools.repo file first."
84+
},
85+
"zypper": {
86+
"available": false,
87+
"package": "tui-firewall",
88+
"repo": "tui-tools",
89+
"requires_repo_setup": true,
90+
"command": "sudo zypper install tui-firewall",
91+
"url": "https://pkgs.tui.tools/rpm",
92+
"note": "Add the tui-tools repository first."
93+
},
94+
"binary": {
95+
"available": true,
96+
"pattern": "tui-firewall_{version}_linux_{arch}.tar.gz",
97+
"command": "curl -fsSL https://github.com/tui-tools/tui-firewall/releases/download/v{version}/tui-firewall_{version}_linux_{arch}.tar.gz | tar -xz tui-firewall\nsudo install -m0755 tui-firewall /usr/local/bin/tui-firewall",
98+
"url": "https://github.com/tui-tools/tui-firewall/releases",
99+
"note": "One static binary. Verify it against checksums.txt from the same release."
100+
},
101+
"source": {
102+
"available": true,
103+
"command": "git clone https://github.com/tui-tools/tui-firewall\ncd tui-firewall && make build\nsudo install -m0755 bin/tui-firewall /usr/local/bin/tui-firewall",
104+
"url": "https://github.com/tui-tools/tui-firewall",
105+
"note": "Needs Go 1.26 or newer."
106+
}
107+
},
108+
"security": {
109+
"needs_sudo": "Reading ufw's state needs root, and so does every change: add, delete, enable, disable, reload, default policy and logging level. Escalation goes through `sudo -n`, which never prompts, and `--sudo \"\"` runs the command directly when you are already root.",
110+
"preview_before_run": true,
111+
"no_daemon": true,
112+
"no_network": true,
113+
"static_binary": true,
114+
"signed_releases": false,
115+
"config_paths": [
116+
"/etc/tui-firewall/config.toml",
117+
"~/.config/tui-firewall/config.toml"
118+
]
119+
},
120+
"maintainers": [
121+
{ "name": "Edimar Cardoso", "github": "edimarlnx" }
122+
],
123+
"since": "2026-08-29",
124+
"keywords": ["ufw", "firewalld", "iptables", "nftables", "firewall", "tui", "bubbletea"]
125+
}

0 commit comments

Comments
 (0)