detached bfed184

ci(release): publish GitHub releases and AUR packages with GoReleaser (#58)

Tags build linux amd64/arm64 archives, checksums and provenance. neferwl-bin and neferwl-git are built with makepkg, checksum-verified for both arches, then pushed to the AUR.
commit
bfed18494f367dd5f869052eb3c0a8dddf5ba1c2
author
bnema · · 2026-09-29 05:12 UTC
committer
GitHub · · 2026-09-29 05:12 UTC
parent
e0b15ca
signature
GPG UnverifiedB5690EEEBB952194 The key is unknown
6 files · +390 -2
M .github/workflows/ci.yml +2 -0
@@ -3,6 +3,8 @@ on:
33 push:
44 branches: [main]
55 pull_request:
6+ # The release workflow runs these checks before it publishes.
7+ workflow_call:
68 concurrency:
79 group: ci-${{ github.ref }}
810 cancel-in-progress: true
@@ -3,6 +3,8 @@ on:
3 push:3 push:
4 branches: [main]4 branches: [main]
5 pull_request:5 pull_request:
6+ # The release workflow runs these checks before it publishes.
7+ workflow_call:
6 concurrency:8 concurrency:
7 group: ci-${{ github.ref }}9 group: ci-${{ github.ref }}
8 cancel-in-progress: true10 cancel-in-progress: true
A .github/workflows/release.yml +93 -0
@@ -0,0 +1,93 @@
1+name: Release
2+on:
3+ push:
4+ tags: ['v*']
5+permissions:
6+ contents: read
7+concurrency:
8+ group: release-${{ github.ref }}
9+ cancel-in-progress: false
10+jobs:
11+ check:
12+ uses: ./.github/workflows/ci.yml
13+
14+ release:
15+ needs: check
16+ runs-on: ubuntu-latest
17+ permissions:
18+ contents: write # create the release
19+ id-token: write # sign the provenance attestation
20+ attestations: write
21+ steps:
22+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
23+ with:
24+ fetch-depth: 0
25+ persist-credentials: false
26+ - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
27+ with:
28+ go-version-file: go.mod
29+ - uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7.2.3
30+ with:
31+ distribution: goreleaser
32+ version: '~> v2'
33+ args: release --clean
34+ env:
35+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36+ - uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2
37+ with:
38+ subject-path: |
39+ dist/*.tar.gz
40+ dist/checksums.txt
41+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
42+ with:
43+ name: aur-bin
44+ path: dist/aur/neferwl-bin.pkgbuild
45+ if-no-files-found: error
46+
47+ # makepkg must run on Arch as a non-root user. publish.sh builds each
48+ # package, verifies every source checksum, then pushes it.
49+ aur:
50+ needs: release
51+ runs-on: ubuntu-latest
52+ container:
53+ image: archlinux:latest
54+ strategy:
55+ fail-fast: false
56+ matrix:
57+ pkg: [neferwl-bin, neferwl-git]
58+ # Pre-releases (v0.2.0-rc1) stay off the AUR: pacman sorts 0.2.0.rc1
59+ # after 0.2.0, so the final release would not look like an upgrade.
60+ env:
61+ SKIP: ${{ contains(github.ref_name, '-') }}
62+ steps:
63+ - run: >-
64+ pacman -Syu --noconfirm --needed
65+ base-devel git openssh sudo
66+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
67+ with:
68+ persist-credentials: false
69+ - if: matrix.pkg == 'neferwl-bin' && env.SKIP != 'true'
70+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
71+ with:
72+ name: aur-bin
73+ path: aur-bin
74+ - name: Create the build user
75+ run: |
76+ useradd -m builder
77+ echo 'builder ALL=(root) NOPASSWD: /usr/bin/pacman' >/etc/sudoers.d/builder
78+ - name: Build, verify and publish ${{ matrix.pkg }}
79+ if: env.SKIP != 'true'
80+ env:
81+ AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
82+ AUR_USERNAME: ${{ secrets.AUR_USERNAME }}
83+ AUR_EMAIL: ${{ secrets.AUR_EMAIL }}
84+ PKG: ${{ matrix.pkg }}
85+ run: |
86+ if [ "$PKG" = neferwl-bin ]; then
87+ pkgbuild=aur-bin/neferwl-bin.pkgbuild
88+ else
89+ pkgbuild=packaging/aur/neferwl-git/PKGBUILD
90+ fi
91+ chmod -R a+rX "$GITHUB_WORKSPACE"
92+ sudo -u builder --preserve-env=AUR_SSH_PRIVATE_KEY,AUR_USERNAME,AUR_EMAIL \
93+ packaging/aur/publish.sh "$PKG" "$pkgbuild"
@@ -0,0 +1,93 @@
1+name: Release
2+on:
3+ push:
4+ tags: ['v*']
5+permissions:
6+ contents: read
7+concurrency:
8+ group: release-${{ github.ref }}
9+ cancel-in-progress: false
10+jobs:
11+ check:
12+ uses: ./.github/workflows/ci.yml
13+
14+ release:
15+ needs: check
16+ runs-on: ubuntu-latest
17+ permissions:
18+ contents: write # create the release
19+ id-token: write # sign the provenance attestation
20+ attestations: write
21+ steps:
22+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
23+ with:
24+ fetch-depth: 0
25+ persist-credentials: false
26+ - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
27+ with:
28+ go-version-file: go.mod
29+ - uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7.2.3
30+ with:
31+ distribution: goreleaser
32+ version: '~> v2'
33+ args: release --clean
34+ env:
35+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36+ - uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2
37+ with:
38+ subject-path: |
39+ dist/*.tar.gz
40+ dist/checksums.txt
41+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
42+ with:
43+ name: aur-bin
44+ path: dist/aur/neferwl-bin.pkgbuild
45+ if-no-files-found: error
46+
47+ # makepkg must run on Arch as a non-root user. publish.sh builds each
48+ # package, verifies every source checksum, then pushes it.
49+ aur:
50+ needs: release
51+ runs-on: ubuntu-latest
52+ container:
53+ image: archlinux:latest
54+ strategy:
55+ fail-fast: false
56+ matrix:
57+ pkg: [neferwl-bin, neferwl-git]
58+ # Pre-releases (v0.2.0-rc1) stay off the AUR: pacman sorts 0.2.0.rc1
59+ # after 0.2.0, so the final release would not look like an upgrade.
60+ env:
61+ SKIP: ${{ contains(github.ref_name, '-') }}
62+ steps:
63+ - run: >-
64+ pacman -Syu --noconfirm --needed
65+ base-devel git openssh sudo
66+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
67+ with:
68+ persist-credentials: false
69+ - if: matrix.pkg == 'neferwl-bin' && env.SKIP != 'true'
70+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
71+ with:
72+ name: aur-bin
73+ path: aur-bin
74+ - name: Create the build user
75+ run: |
76+ useradd -m builder
77+ echo 'builder ALL=(root) NOPASSWD: /usr/bin/pacman' >/etc/sudoers.d/builder
78+ - name: Build, verify and publish ${{ matrix.pkg }}
79+ if: env.SKIP != 'true'
80+ env:
81+ AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
82+ AUR_USERNAME: ${{ secrets.AUR_USERNAME }}
83+ AUR_EMAIL: ${{ secrets.AUR_EMAIL }}
84+ PKG: ${{ matrix.pkg }}
85+ run: |
86+ if [ "$PKG" = neferwl-bin ]; then
87+ pkgbuild=aur-bin/neferwl-bin.pkgbuild
88+ else
89+ pkgbuild=packaging/aur/neferwl-git/PKGBUILD
90+ fi
91+ chmod -R a+rX "$GITHUB_WORKSPACE"
92+ sudo -u builder --preserve-env=AUR_SSH_PRIVATE_KEY,AUR_USERNAME,AUR_EMAIL \
93+ packaging/aur/publish.sh "$PKG" "$pkgbuild"
A .goreleaser.yaml +153 -0
@@ -0,0 +1,153 @@
1+# Builds the GitHub release for a pushed v* tag (.github/workflows/release.yml)
2+# and generates the neferwl-bin PKGBUILD. The workflow verifies that PKGBUILD
3+# with makepkg before it pushes it to the AUR, so GoReleaser never uploads it.
4+version: 2
5+
6+project_name: neferwl
7+
8+before:
9+ hooks:
10+ - go mod verify
11+
12+builds:
13+ - id: neferwl
14+ main: ./cmd/neferwl
15+ binary: neferwl
16+ env:
17+ - CGO_ENABLED=0
18+ goos: [linux]
19+ goarch: [amd64, arm64]
20+ flags:
21+ - -trimpath
22+ - -buildmode=pie
23+ ldflags:
24+ - -s -w -X main.version={{ .Version }}
25+ # Same inputs give the same binary.
26+ mod_timestamp: "{{ .CommitTimestamp }}"
27+
28+archives:
29+ - id: neferwl
30+ ids: [neferwl]
31+ name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
32+ formats: [tar.gz]
33+ # Everything the PKGBUILD package() installs, at the paths of the repo.
34+ files:
35+ - LICENSE
36+ - README.md
37+ - examples/config
38+ - packaging/neferwl-session
39+ - packaging/neferwl.service
40+ - packaging/neferwl-shutdown.target
41+ - packaging/neferwl.desktop
42+ - packaging/neferwl-portals.conf
43+
44+checksum:
45+ name_template: checksums.txt
46+ algorithm: sha256
47+
48+snapshot:
49+ version_template: "{{ incpatch .Version }}-next"
50+
51+git:
52+ tag_sort: -version:refname
53+
54+changelog:
55+ sort: asc
56+ use: github
57+ filters:
58+ exclude:
59+ - "^style(\\([^)]+\\))?:"
60+ - "^test(\\([^)]+\\))?:"
61+ groups:
62+ - title: Added
63+ regexp: "^feat(\\([^)]+\\))?!?:"
64+ order: 0
65+ - title: Fixed
66+ regexp: "^fix(\\([^)]+\\))?!?:"
67+ order: 1
68+ - title: Performance
69+ regexp: "^perf(\\([^)]+\\))?!?:"
70+ order: 2
71+ - title: Changed
72+ regexp: "^(refactor|build)(\\([^)]+\\))?!?:"
73+ order: 3
74+ - title: Documentation
75+ regexp: "^docs(\\([^)]+\\))?!?:"
76+ order: 4
77+ - title: Maintenance
78+ regexp: "^(chore|ci)(\\([^)]+\\))?!?:"
79+ order: 5
80+ - title: Other changes
81+ order: 999
82+
83+release:
84+ github:
85+ owner: bnema
86+ name: neferwl
87+ draft: false
88+ prerelease: auto
89+ mode: replace
90+ header: |
91+ ## NeferWL {{ .Tag }}
92+
93+ ### Install on Arch Linux
94+
95+ ```sh
96+ paru -S neferwl-bin # this release, pre-built (x86_64, aarch64)
97+ paru -S neferwl-git # latest main, built from source
98+ ```
99+
100+ ### Install the pre-built archive
101+
102+ Linux amd64 and arm64. Replace `amd64` with `arm64` on ARM.
103+
104+ ```sh
105+ gh release download {{ .Tag }} -R bnema/neferwl -p 'neferwl_{{ .Version }}_linux_amd64.tar.gz' -p checksums.txt
106+ sha256sum -c --ignore-missing checksums.txt
107+ gh attestation verify neferwl_{{ .Version }}_linux_amd64.tar.gz -R bnema/neferwl
108+ ```
109+
110+ The archive holds the `neferwl` binary, the session files from `packaging/` and `examples/config`. See the [README](https://github.com/bnema/neferwl#readme) for runtime dependencies and the session setup.
111+ footer: |
112+ ---
113+
114+ **Full changelog**: https://github.com/bnema/neferwl/compare/{{ .PreviousTag }}...{{ .Tag }}
115+
116+aurs:
117+ - name: neferwl-bin
118+ ids: [neferwl]
119+ homepage: https://github.com/bnema/neferwl
120+ description: Minimal Wayland compositor with column tiling, for the TTY
121+ maintainers:
122+ - "bnema <b at bnema dot dev>"
123+ license: GPL-3.0-only
124+ # The release workflow verifies and publishes the generated PKGBUILD.
125+ skip_upload: true
126+ provides: [neferwl]
127+ conflicts: [neferwl, neferwl-git]
128+ # Loaded at runtime (purego, no cgo): not seen by makepkg's library scan.
129+ depends:
130+ - glibc
131+ - libinput
132+ - libxkbcommon
133+ - seatd
134+ - systemd-libs
135+ - vulkan-icd-loader
136+ - vulkan-driver
137+ - wayland
138+ - dbus
139+ optdepends:
140+ - "xwayland-satellite>=0.7: X11 apps"
141+ - "foot: default terminal"
142+ - "fuzzel: launcher"
143+ - "xdg-desktop-portal-gtk: file pickers and settings for apps"
144+ package: |-
145+ install -Dm755 ./neferwl "${pkgdir}/usr/bin/neferwl"
146+ install -Dm755 ./packaging/neferwl-session "${pkgdir}/usr/bin/neferwl-session"
147+ install -Dm644 ./packaging/neferwl.service "${pkgdir}/usr/lib/systemd/user/neferwl.service"
148+ install -Dm644 ./packaging/neferwl-shutdown.target "${pkgdir}/usr/lib/systemd/user/neferwl-shutdown.target"
149+ install -Dm644 ./packaging/neferwl.desktop "${pkgdir}/usr/share/wayland-sessions/neferwl.desktop"
150+ install -Dm644 ./packaging/neferwl-portals.conf "${pkgdir}/usr/share/xdg-desktop-portal/neferwl-portals.conf"
151+ install -Dm644 ./examples/config "${pkgdir}/usr/share/doc/neferwl/config.example"
152+ install -Dm644 ./README.md "${pkgdir}/usr/share/doc/neferwl/README.md"
153+ install -Dm644 ./LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
@@ -0,0 +1,153 @@
1+# Builds the GitHub release for a pushed v* tag (.github/workflows/release.yml)
2+# and generates the neferwl-bin PKGBUILD. The workflow verifies that PKGBUILD
3+# with makepkg before it pushes it to the AUR, so GoReleaser never uploads it.
4+version: 2
5+
6+project_name: neferwl
7+
8+before:
9+ hooks:
10+ - go mod verify
11+
12+builds:
13+ - id: neferwl
14+ main: ./cmd/neferwl
15+ binary: neferwl
16+ env:
17+ - CGO_ENABLED=0
18+ goos: [linux]
19+ goarch: [amd64, arm64]
20+ flags:
21+ - -trimpath
22+ - -buildmode=pie
23+ ldflags:
24+ - -s -w -X main.version={{ .Version }}
25+ # Same inputs give the same binary.
26+ mod_timestamp: "{{ .CommitTimestamp }}"
27+
28+archives:
29+ - id: neferwl
30+ ids: [neferwl]
31+ name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
32+ formats: [tar.gz]
33+ # Everything the PKGBUILD package() installs, at the paths of the repo.
34+ files:
35+ - LICENSE
36+ - README.md
37+ - examples/config
38+ - packaging/neferwl-session
39+ - packaging/neferwl.service
40+ - packaging/neferwl-shutdown.target
41+ - packaging/neferwl.desktop
42+ - packaging/neferwl-portals.conf
43+
44+checksum:
45+ name_template: checksums.txt
46+ algorithm: sha256
47+
48+snapshot:
49+ version_template: "{{ incpatch .Version }}-next"
50+
51+git:
52+ tag_sort: -version:refname
53+
54+changelog:
55+ sort: asc
56+ use: github
57+ filters:
58+ exclude:
59+ - "^style(\\([^)]+\\))?:"
60+ - "^test(\\([^)]+\\))?:"
61+ groups:
62+ - title: Added
63+ regexp: "^feat(\\([^)]+\\))?!?:"
64+ order: 0
65+ - title: Fixed
66+ regexp: "^fix(\\([^)]+\\))?!?:"
67+ order: 1
68+ - title: Performance
69+ regexp: "^perf(\\([^)]+\\))?!?:"
70+ order: 2
71+ - title: Changed
72+ regexp: "^(refactor|build)(\\([^)]+\\))?!?:"
73+ order: 3
74+ - title: Documentation
75+ regexp: "^docs(\\([^)]+\\))?!?:"
76+ order: 4
77+ - title: Maintenance
78+ regexp: "^(chore|ci)(\\([^)]+\\))?!?:"
79+ order: 5
80+ - title: Other changes
81+ order: 999
82+
83+release:
84+ github:
85+ owner: bnema
86+ name: neferwl
87+ draft: false
88+ prerelease: auto
89+ mode: replace
90+ header: |
91+ ## NeferWL {{ .Tag }}
92+
93+ ### Install on Arch Linux
94+
95+ ```sh
96+ paru -S neferwl-bin # this release, pre-built (x86_64, aarch64)
97+ paru -S neferwl-git # latest main, built from source
98+ ```
99+
100+ ### Install the pre-built archive
101+
102+ Linux amd64 and arm64. Replace `amd64` with `arm64` on ARM.
103+
104+ ```sh
105+ gh release download {{ .Tag }} -R bnema/neferwl -p 'neferwl_{{ .Version }}_linux_amd64.tar.gz' -p checksums.txt
106+ sha256sum -c --ignore-missing checksums.txt
107+ gh attestation verify neferwl_{{ .Version }}_linux_amd64.tar.gz -R bnema/neferwl
108+ ```
109+
110+ The archive holds the `neferwl` binary, the session files from `packaging/` and `examples/config`. See the [README](https://github.com/bnema/neferwl#readme) for runtime dependencies and the session setup.
111+ footer: |
112+ ---
113+
114+ **Full changelog**: https://github.com/bnema/neferwl/compare/{{ .PreviousTag }}...{{ .Tag }}
115+
116+aurs:
117+ - name: neferwl-bin
118+ ids: [neferwl]
119+ homepage: https://github.com/bnema/neferwl
120+ description: Minimal Wayland compositor with column tiling, for the TTY
121+ maintainers:
122+ - "bnema <b at bnema dot dev>"
123+ license: GPL-3.0-only
124+ # The release workflow verifies and publishes the generated PKGBUILD.
125+ skip_upload: true
126+ provides: [neferwl]
127+ conflicts: [neferwl, neferwl-git]
128+ # Loaded at runtime (purego, no cgo): not seen by makepkg's library scan.
129+ depends:
130+ - glibc
131+ - libinput
132+ - libxkbcommon
133+ - seatd
134+ - systemd-libs
135+ - vulkan-icd-loader
136+ - vulkan-driver
137+ - wayland
138+ - dbus
139+ optdepends:
140+ - "xwayland-satellite>=0.7: X11 apps"
141+ - "foot: default terminal"
142+ - "fuzzel: launcher"
143+ - "xdg-desktop-portal-gtk: file pickers and settings for apps"
144+ package: |-
145+ install -Dm755 ./neferwl "${pkgdir}/usr/bin/neferwl"
146+ install -Dm755 ./packaging/neferwl-session "${pkgdir}/usr/bin/neferwl-session"
147+ install -Dm644 ./packaging/neferwl.service "${pkgdir}/usr/lib/systemd/user/neferwl.service"
148+ install -Dm644 ./packaging/neferwl-shutdown.target "${pkgdir}/usr/lib/systemd/user/neferwl-shutdown.target"
149+ install -Dm644 ./packaging/neferwl.desktop "${pkgdir}/usr/share/wayland-sessions/neferwl.desktop"
150+ install -Dm644 ./packaging/neferwl-portals.conf "${pkgdir}/usr/share/xdg-desktop-portal/neferwl-portals.conf"
151+ install -Dm644 ./examples/config "${pkgdir}/usr/share/doc/neferwl/config.example"
152+ install -Dm644 ./README.md "${pkgdir}/usr/share/doc/neferwl/README.md"
153+ install -Dm644 ./LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
M README.md +15 -2
@@ -74,7 +74,14 @@ NeferWL runs on Linux. It needs a GPU and kernel driver with atomic KMS, and a V
7474
7575 ## Install (Arch Linux)
7676
77-Building needs Go 1.27.
77+From the AUR:
78+
79+```sh
80+paru -S neferwl-bin # latest release, pre-built for x86_64 and aarch64
81+paru -S neferwl-git # latest main, built from source
82+```
83+
84+From a checkout (needs Go 1.27):
7885
7986 ```sh
8087 make pkg # builds dist/neferwl-*.pkg.tar.zst from HEAD
@@ -83,7 +90,13 @@ sudo pacman -U dist/neferwl-*.pkg.tar.zst
8390
8491 The package installs `neferwl` and a **NeferWL** session for display managers such as Ly, GDM and SDDM. The session runs `neferwl-session`, which starts `neferwl.service` under systemd. This starts `graphical-session.target` and services bound to it (bars, notification daemons, portals, and XDG autostart) with NeferWL and stops them with it. Running `neferwl --session` alone still exports the display environment to D-Bus and systemd user services.
8592
86-On other distributions, `make build` builds `bin/neferwl`.
93+On other distributions, download a `linux_amd64` or `linux_arm64` archive from [Releases](https://github.com/bnema/neferwl/releases) and check it against `checksums.txt`, or run `make bin` to build `bin/neferwl`.
94+
95+## Releases
96+
97+Pushing a `v*` tag runs `.github/workflows/release.yml`. It runs the CI checks, then GoReleaser builds the archives, `checksums.txt`, a provenance attestation and the GitHub release. Last, `packaging/aur/publish.sh` builds `neferwl-bin` and `neferwl-git` with makepkg, checks every source checksum for x86_64 and aarch64, and pushes them to the AUR. Pre-release tags (`v0.2.0-rc1`) get a GitHub release and are kept off the AUR.
98+
99+The workflow needs the `AUR_SSH_PRIVATE_KEY`, `AUR_USERNAME` and `AUR_EMAIL` repository secrets.
87100
88101 ## Configuration
89102
@@ -74,7 +74,14 @@ NeferWL runs on Linux. It needs a GPU and kernel driver with atomic KMS, and a V
74 74
75 ## Install (Arch Linux)75 ## Install (Arch Linux)
76 76
77-Building needs Go 1.27.77+From the AUR:
78+
79+```sh
80+paru -S neferwl-bin # latest release, pre-built for x86_64 and aarch64
81+paru -S neferwl-git # latest main, built from source
82+```
83+
84+From a checkout (needs Go 1.27):
78 85
79 ```sh86 ```sh
80 make pkg # builds dist/neferwl-*.pkg.tar.zst from HEAD87 make pkg # builds dist/neferwl-*.pkg.tar.zst from HEAD
@@ -83,7 +90,13 @@ sudo pacman -U dist/neferwl-*.pkg.tar.zst
83 90
84 The package installs `neferwl` and a **NeferWL** session for display managers such as Ly, GDM and SDDM. The session runs `neferwl-session`, which starts `neferwl.service` under systemd. This starts `graphical-session.target` and services bound to it (bars, notification daemons, portals, and XDG autostart) with NeferWL and stops them with it. Running `neferwl --session` alone still exports the display environment to D-Bus and systemd user services.91 The package installs `neferwl` and a **NeferWL** session for display managers such as Ly, GDM and SDDM. The session runs `neferwl-session`, which starts `neferwl.service` under systemd. This starts `graphical-session.target` and services bound to it (bars, notification daemons, portals, and XDG autostart) with NeferWL and stops them with it. Running `neferwl --session` alone still exports the display environment to D-Bus and systemd user services.
85 92
86-On other distributions, `make build` builds `bin/neferwl`.93+On other distributions, download a `linux_amd64` or `linux_arm64` archive from [Releases](https://github.com/bnema/neferwl/releases) and check it against `checksums.txt`, or run `make bin` to build `bin/neferwl`.
94+
95+## Releases
96+
97+Pushing a `v*` tag runs `.github/workflows/release.yml`. It runs the CI checks, then GoReleaser builds the archives, `checksums.txt`, a provenance attestation and the GitHub release. Last, `packaging/aur/publish.sh` builds `neferwl-bin` and `neferwl-git` with makepkg, checks every source checksum for x86_64 and aarch64, and pushes them to the AUR. Pre-release tags (`v0.2.0-rc1`) get a GitHub release and are kept off the AUR.
98+
99+The workflow needs the `AUR_SSH_PRIVATE_KEY`, `AUR_USERNAME` and `AUR_EMAIL` repository secrets.
87 100
88 ## Configuration101 ## Configuration
89 102
A packaging/aur/neferwl-git/PKGBUILD +61 -0
@@ -0,0 +1,61 @@
1+# Maintainer: bnema <b at bnema dot dev>
2+# The release workflow sets pkgver and publishes this file to the AUR on every
3+# release tag, so the AUR version never falls behind the latest tag.
4+pkgname=neferwl-git
5+pkgver=0.1.0.r78.ge0b15ca
6+pkgrel=1
7+pkgdesc='Minimal Wayland compositor with column tiling, for the TTY (git version)'
8+arch=('x86_64' 'aarch64')
9+url='https://github.com/bnema/neferwl'
10+license=('GPL-3.0-only')
11+# Loaded at runtime (purego, no cgo): not seen by makepkg's library scan.
12+depends=('glibc' 'libinput' 'libxkbcommon' 'seatd' 'systemd-libs' 'vulkan-icd-loader'
13+ 'vulkan-driver' 'wayland' 'dbus')
14+makedepends=('go>=2:1.27' 'git')
15+optdepends=('xwayland-satellite>=0.7: X11 apps'
16+ 'foot: default terminal'
17+ 'fuzzel: launcher'
18+ 'xdg-desktop-portal-gtk: file pickers and settings for apps')
19+provides=('neferwl')
20+conflicts=('neferwl' 'neferwl-bin')
21+source=('git+https://github.com/bnema/neferwl.git')
22+sha256sums=('SKIP')
23+
24+pkgver() {
25+ cd neferwl
26+ # v0.2.0-5-gabc1234 -> 0.2.0.r5.gabc1234. Pre-release tags (v0.3.0-rc1)
27+ # are skipped: pacman sorts 0.3.0.rc1 after 0.3.0.
28+ git describe --long --tags --abbrev=7 --exclude='*-*' | sed 's/^v//;s/\([^-]*-g\)/r\1/;s/-/./g'
29+}
30+
31+prepare() {
32+ cd neferwl
33+ export GOPATH="$srcdir/gopath" GOFLAGS='-mod=readonly -modcacherw' GOTOOLCHAIN=local
34+ go mod download
35+}
36+
37+build() {
38+ cd neferwl
39+ export GOPATH="$srcdir/gopath" CGO_ENABLED=0 GOTOOLCHAIN=local GOPROXY=off
40+ export GOFLAGS='-mod=readonly -modcacherw -trimpath -buildvcs=false -buildmode=pie'
41+ go build -ldflags "-X main.version=$pkgver" -o neferwl ./cmd/neferwl
42+}
43+
44+check() {
45+ cd neferwl
46+ ./neferwl version
47+ ./neferwl validate-config examples/config
48+}
49+
50+package() {
51+ cd neferwl
52+ install -Dm755 neferwl "$pkgdir/usr/bin/neferwl"
53+ install -Dm755 packaging/neferwl-session "$pkgdir/usr/bin/neferwl-session"
54+ install -Dm644 packaging/neferwl.service "$pkgdir/usr/lib/systemd/user/neferwl.service"
55+ install -Dm644 packaging/neferwl-shutdown.target "$pkgdir/usr/lib/systemd/user/neferwl-shutdown.target"
56+ install -Dm644 packaging/neferwl.desktop "$pkgdir/usr/share/wayland-sessions/neferwl.desktop"
57+ install -Dm644 packaging/neferwl-portals.conf "$pkgdir/usr/share/xdg-desktop-portal/neferwl-portals.conf"
58+ install -Dm644 examples/config "$pkgdir/usr/share/doc/neferwl/config.example"
59+ install -Dm644 README.md "$pkgdir/usr/share/doc/neferwl/README.md"
60+ install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
61+}
@@ -0,0 +1,61 @@
1+# Maintainer: bnema <b at bnema dot dev>
2+# The release workflow sets pkgver and publishes this file to the AUR on every
3+# release tag, so the AUR version never falls behind the latest tag.
4+pkgname=neferwl-git
5+pkgver=0.1.0.r78.ge0b15ca
6+pkgrel=1
7+pkgdesc='Minimal Wayland compositor with column tiling, for the TTY (git version)'
8+arch=('x86_64' 'aarch64')
9+url='https://github.com/bnema/neferwl'
10+license=('GPL-3.0-only')
11+# Loaded at runtime (purego, no cgo): not seen by makepkg's library scan.
12+depends=('glibc' 'libinput' 'libxkbcommon' 'seatd' 'systemd-libs' 'vulkan-icd-loader'
13+ 'vulkan-driver' 'wayland' 'dbus')
14+makedepends=('go>=2:1.27' 'git')
15+optdepends=('xwayland-satellite>=0.7: X11 apps'
16+ 'foot: default terminal'
17+ 'fuzzel: launcher'
18+ 'xdg-desktop-portal-gtk: file pickers and settings for apps')
19+provides=('neferwl')
20+conflicts=('neferwl' 'neferwl-bin')
21+source=('git+https://github.com/bnema/neferwl.git')
22+sha256sums=('SKIP')
23+
24+pkgver() {
25+ cd neferwl
26+ # v0.2.0-5-gabc1234 -> 0.2.0.r5.gabc1234. Pre-release tags (v0.3.0-rc1)
27+ # are skipped: pacman sorts 0.3.0.rc1 after 0.3.0.
28+ git describe --long --tags --abbrev=7 --exclude='*-*' | sed 's/^v//;s/\([^-]*-g\)/r\1/;s/-/./g'
29+}
30+
31+prepare() {
32+ cd neferwl
33+ export GOPATH="$srcdir/gopath" GOFLAGS='-mod=readonly -modcacherw' GOTOOLCHAIN=local
34+ go mod download
35+}
36+
37+build() {
38+ cd neferwl
39+ export GOPATH="$srcdir/gopath" CGO_ENABLED=0 GOTOOLCHAIN=local GOPROXY=off
40+ export GOFLAGS='-mod=readonly -modcacherw -trimpath -buildvcs=false -buildmode=pie'
41+ go build -ldflags "-X main.version=$pkgver" -o neferwl ./cmd/neferwl
42+}
43+
44+check() {
45+ cd neferwl
46+ ./neferwl version
47+ ./neferwl validate-config examples/config
48+}
49+
50+package() {
51+ cd neferwl
52+ install -Dm755 neferwl "$pkgdir/usr/bin/neferwl"
53+ install -Dm755 packaging/neferwl-session "$pkgdir/usr/bin/neferwl-session"
54+ install -Dm644 packaging/neferwl.service "$pkgdir/usr/lib/systemd/user/neferwl.service"
55+ install -Dm644 packaging/neferwl-shutdown.target "$pkgdir/usr/lib/systemd/user/neferwl-shutdown.target"
56+ install -Dm644 packaging/neferwl.desktop "$pkgdir/usr/share/wayland-sessions/neferwl.desktop"
57+ install -Dm644 packaging/neferwl-portals.conf "$pkgdir/usr/share/xdg-desktop-portal/neferwl-portals.conf"
58+ install -Dm644 examples/config "$pkgdir/usr/share/doc/neferwl/config.example"
59+ install -Dm644 README.md "$pkgdir/usr/share/doc/neferwl/README.md"
60+ install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
61+}
A packaging/aur/publish.sh +66 -0
@@ -0,0 +1,66 @@
1+#!/usr/bin/env bash
2+# Builds an AUR package with makepkg, then pushes its PKGBUILD and .SRCINFO.
3+# makepkg downloads every source and checks its sha256sum, so a PKGBUILD that
4+# does not build, or does not match its release assets, is never published.
5+#
6+# Usage: publish.sh <pkgname> <PKGBUILD>
7+# Env: AUR_SSH_PRIVATE_KEY, AUR_USERNAME, AUR_EMAIL
8+# DRY_RUN=1 builds and prints the files without pushing.
9+# Runs as a non-root user that may run pacman through sudo (makepkg -s).
10+set -euo pipefail
11+CARCH=$(uname -m)
12+
13+pkgname=$1
14+work=$(mktemp -d)
15+trap 'rm -rf "$work"' EXIT
16+cp "$2" "$work/PKGBUILD"
17+cd "$work"
18+
19+makepkg --syncdeps --force --noconfirm
20+# A -git pkgver() rewrites pkgver in PKGBUILD; .SRCINFO must match it.
21+makepkg --printsrcinfo >.SRCINFO
22+pkgver=$(sed -n 's/^\tpkgver = //p' .SRCINFO)
23+
24+# makepkg only fetches the sources of this machine's arch: check the others too.
25+while read -r arch; do
26+ if [[ $arch == "$CARCH" ]] || ! grep -q "^source_$arch=" PKGBUILD; then
27+ continue
28+ fi
29+ { cat /etc/makepkg.conf; echo "CARCH=$arch"; } >"makepkg-$arch.conf"
30+ makepkg --config "makepkg-$arch.conf" --verifysource --noconfirm
31+done < <(sed -n 's/^\tarch = //p' .SRCINFO)
32+
33+# pacman versions use _ where the tag has - (0.2.0-rc1 -> 0.2.0_rc1).
34+got=$("pkg/$pkgname/usr/bin/neferwl" version)
35+if [[ $got != "$pkgver" && $got != "${pkgver//_/-}" ]]; then
36+ echo "packaged neferwl reports version $got, want $pkgver" >&2
37+ exit 1
38+fi
39+
40+if [[ ${DRY_RUN:-} == 1 ]]; then
41+ cat PKGBUILD .SRCINFO
42+ exit 0
43+fi
44+
45+ssh_dir=$HOME/.ssh
46+key=$ssh_dir/aur
47+install -d -m 700 "$ssh_dir"
48+(umask 077 && printf '%s\n' "$AUR_SSH_PRIVATE_KEY" >"$key")
49+# Pinned host key. Fingerprint SHA256:RFzBCUItH9LZS0cKB5UE6ceAYhBD5C8GeOBip8Z11+4
50+# is published on https://aur.archlinux.org.
51+echo 'aur.archlinux.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEuBKrPzbawxA/k2g6NcyV5jmqwJ2s+zpgZGZ7tpLIcN' >"$ssh_dir/known_hosts"
52+export GIT_SSH_COMMAND="ssh -i $key -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile=$ssh_dir/known_hosts"
53+
54+git clone "ssh://aur@aur.archlinux.org/$pkgname.git" aur
55+cp PKGBUILD .SRCINFO aur/
56+cd aur
57+git add PKGBUILD .SRCINFO
58+if git diff --cached --quiet; then
59+ echo "$pkgname $pkgver is already on the AUR"
60+ exit 0
61+fi
62+# Commits are signed with the AUR SSH key.
63+git -c user.name="$AUR_USERNAME" -c user.email="$AUR_EMAIL" \
64+ -c gpg.format=ssh -c user.signingkey="$key" \
65+ commit -S -m "Update to $pkgver"
66+git push origin HEAD:master
@@ -0,0 +1,66 @@
1+#!/usr/bin/env bash
2+# Builds an AUR package with makepkg, then pushes its PKGBUILD and .SRCINFO.
3+# makepkg downloads every source and checks its sha256sum, so a PKGBUILD that
4+# does not build, or does not match its release assets, is never published.
5+#
6+# Usage: publish.sh <pkgname> <PKGBUILD>
7+# Env: AUR_SSH_PRIVATE_KEY, AUR_USERNAME, AUR_EMAIL
8+# DRY_RUN=1 builds and prints the files without pushing.
9+# Runs as a non-root user that may run pacman through sudo (makepkg -s).
10+set -euo pipefail
11+CARCH=$(uname -m)
12+
13+pkgname=$1
14+work=$(mktemp -d)
15+trap 'rm -rf "$work"' EXIT
16+cp "$2" "$work/PKGBUILD"
17+cd "$work"
18+
19+makepkg --syncdeps --force --noconfirm
20+# A -git pkgver() rewrites pkgver in PKGBUILD; .SRCINFO must match it.
21+makepkg --printsrcinfo >.SRCINFO
22+pkgver=$(sed -n 's/^\tpkgver = //p' .SRCINFO)
23+
24+# makepkg only fetches the sources of this machine's arch: check the others too.
25+while read -r arch; do
26+ if [[ $arch == "$CARCH" ]] || ! grep -q "^source_$arch=" PKGBUILD; then
27+ continue
28+ fi
29+ { cat /etc/makepkg.conf; echo "CARCH=$arch"; } >"makepkg-$arch.conf"
30+ makepkg --config "makepkg-$arch.conf" --verifysource --noconfirm
31+done < <(sed -n 's/^\tarch = //p' .SRCINFO)
32+
33+# pacman versions use _ where the tag has - (0.2.0-rc1 -> 0.2.0_rc1).
34+got=$("pkg/$pkgname/usr/bin/neferwl" version)
35+if [[ $got != "$pkgver" && $got != "${pkgver//_/-}" ]]; then
36+ echo "packaged neferwl reports version $got, want $pkgver" >&2
37+ exit 1
38+fi
39+
40+if [[ ${DRY_RUN:-} == 1 ]]; then
41+ cat PKGBUILD .SRCINFO
42+ exit 0
43+fi
44+
45+ssh_dir=$HOME/.ssh
46+key=$ssh_dir/aur
47+install -d -m 700 "$ssh_dir"
48+(umask 077 && printf '%s\n' "$AUR_SSH_PRIVATE_KEY" >"$key")
49+# Pinned host key. Fingerprint SHA256:RFzBCUItH9LZS0cKB5UE6ceAYhBD5C8GeOBip8Z11+4
50+# is published on https://aur.archlinux.org.
51+echo 'aur.archlinux.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEuBKrPzbawxA/k2g6NcyV5jmqwJ2s+zpgZGZ7tpLIcN' >"$ssh_dir/known_hosts"
52+export GIT_SSH_COMMAND="ssh -i $key -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile=$ssh_dir/known_hosts"
53+
54+git clone "ssh://aur@aur.archlinux.org/$pkgname.git" aur
55+cp PKGBUILD .SRCINFO aur/
56+cd aur
57+git add PKGBUILD .SRCINFO
58+if git diff --cached --quiet; then
59+ echo "$pkgname $pkgver is already on the AUR"
60+ exit 0
61+fi
62+# Commits are signed with the AUR SSH key.
63+git -c user.name="$AUR_USERNAME" -c user.email="$AUR_EMAIL" \
64+ -c gpg.format=ssh -c user.signingkey="$key" \
65+ commit -S -m "Update to $pkgver"
66+git push origin HEAD:master

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 25

Tags 10

↑↓ moveenter openesc close