detached dcd34c9

ci(forgejo): add a Forgejo workflow without paths-filter and CodeQL (#11)

Forgejo cannot fetch `dorny/paths-filter` or `github/codeql-action` (not on data.forgejo.org), so `.github/workflows/ci.yml` and `codeql.yml` fail on PRs and Lint/Test never run.

This adds `.forgejo/workflows/ci.yml` with Lint, Test and Installer, without those actions.

Reviewed-on: https://git.bnema.dev/bnema/gordon/pulls/11
commit
dcd34c957693f850627473d38f9b9d2a8801ff35
author
brice · · 2026-10-02 12:43 UTC
committer
bnema · · 2026-10-02 12:43 UTC
parent
f19f453
signature
unsigned
2 files · +57 -0
A .forgejo/workflows/ci.yml +48 -0
@@ -0,0 +1,48 @@
1+# CI for the Forgejo runner. Forgejo reads this directory instead of .github/workflows,
2+# so GitHub keeps its own CI and CodeQL. Actions that do not exist on
3+# data.forgejo.org (dorny/paths-filter, github/codeql-action) are not used here.
4+name: CI
5+
6+on:
7+ push:
8+ branches: [main]
9+ pull_request:
10+
11+jobs:
12+ lint:
13+ name: Lint
14+ runs-on: ubuntu-latest
15+ steps:
16+ - uses: actions/checkout@v6
17+ - uses: actions/setup-go@v5
18+ with:
19+ go-version: "1.27.x"
20+ cache: true
21+ - uses: golangci/golangci-lint-action@v9
22+ with:
23+ version: v2.13.1
24+
25+ test:
26+ name: Test
27+ runs-on: ubuntu-latest
28+ steps:
29+ - uses: actions/checkout@v6
30+ - uses: actions/setup-go@v5
31+ with:
32+ go-version: "1.27.x"
33+ cache: true
34+ - run: go test -race ./...
35+
36+ installer:
37+ name: Installer
38+ runs-on: ubuntu-latest
39+ steps:
40+ - uses: actions/checkout@v6
41+ - name: Install shellcheck
42+ run: |
43+ v=v0.10.0
44+ curl -sSfL "https://github.com/koalaman/shellcheck/releases/download/${v}/shellcheck-${v}.linux.x86_64.tar.xz" | tar -xJ -C "$RUNNER_TEMP"
45+ echo "$RUNNER_TEMP/shellcheck-${v}" >> "$GITHUB_PATH"
46+ - run: |
47+ shellcheck -s sh install.sh tests/install_next_test.sh
48+ sh tests/install_next_test.sh
@@ -0,0 +1,48 @@
1+# CI for the Forgejo runner. Forgejo reads this directory instead of .github/workflows,
2+# so GitHub keeps its own CI and CodeQL. Actions that do not exist on
3+# data.forgejo.org (dorny/paths-filter, github/codeql-action) are not used here.
4+name: CI
5+
6+on:
7+ push:
8+ branches: [main]
9+ pull_request:
10+
11+jobs:
12+ lint:
13+ name: Lint
14+ runs-on: ubuntu-latest
15+ steps:
16+ - uses: actions/checkout@v6
17+ - uses: actions/setup-go@v5
18+ with:
19+ go-version: "1.27.x"
20+ cache: true
21+ - uses: golangci/golangci-lint-action@v9
22+ with:
23+ version: v2.13.1
24+
25+ test:
26+ name: Test
27+ runs-on: ubuntu-latest
28+ steps:
29+ - uses: actions/checkout@v6
30+ - uses: actions/setup-go@v5
31+ with:
32+ go-version: "1.27.x"
33+ cache: true
34+ - run: go test -race ./...
35+
36+ installer:
37+ name: Installer
38+ runs-on: ubuntu-latest
39+ steps:
40+ - uses: actions/checkout@v6
41+ - name: Install shellcheck
42+ run: |
43+ v=v0.10.0
44+ curl -sSfL "https://github.com/koalaman/shellcheck/releases/download/${v}/shellcheck-${v}.linux.x86_64.tar.xz" | tar -xJ -C "$RUNNER_TEMP"
45+ echo "$RUNNER_TEMP/shellcheck-${v}" >> "$GITHUB_PATH"
46+ - run: |
47+ shellcheck -s sh install.sh tests/install_next_test.sh
48+ sh tests/install_next_test.sh
M internal/usecase/logs/service_test.go +9 -0
@@ -40,6 +40,15 @@ func TestService_GetProcessLogs(t *testing.T) {
4040 })
4141
4242 t.Run("returns empty slice for non-existent file", func(t *testing.T) {
43+ // The journalctl fallback must not depend on the host: CI containers have none.
44+ origExec := execCommandContext
45+ execCommandContext = func(ctx context.Context, name string, args ...string) *exec.Cmd {
46+ return exec.CommandContext(ctx, "true") // #nosec G204
47+ }
48+ defer func() {
49+ execCommandContext = origExec
50+ }()
51+
4352 runtime := mocks.NewMockContainerRuntime(t)
4453
4554 svc := NewService("/nonexistent/file.log", true, runtime, log)
@@ -40,6 +40,15 @@ func TestService_GetProcessLogs(t *testing.T) {
40 })40 })
41 41
42 t.Run("returns empty slice for non-existent file", func(t *testing.T) {42 t.Run("returns empty slice for non-existent file", func(t *testing.T) {
43+ // The journalctl fallback must not depend on the host: CI containers have none.
44+ origExec := execCommandContext
45+ execCommandContext = func(ctx context.Context, name string, args ...string) *exec.Cmd {
46+ return exec.CommandContext(ctx, "true") // #nosec G204
47+ }
48+ defer func() {
49+ execCommandContext = origExec
50+ }()
51+
43 runtime := mocks.NewMockContainerRuntime(t)52 runtime := mocks.NewMockContainerRuntime(t)
44 53
45 svc := NewService("/nonexistent/file.log", true, runtime, log)54 svc := NewService("/nonexistent/file.log", true, runtime, log)

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 7

Tags 106

↑↓ moveenter openesc close